1 /-
2 Copyright (c) 2017 Microsoft Corporation. All rights reserved.
3 Released under Apache 2.0 license as described in the file LICENSE.
4 Author: Mario Carneiro
5 -/
6 import data.seq.seq data.seq.computation data.list.basic data.dlist
src └──────────┘ └──────────────────┘ └─────────────┘ └────────┘
7 universes u v w
8
9 /-
10 coinductive wseq (α : Type u) : Type u
11 | nil : wseq α
12 | cons : α → wseq α → wseq α
13 | think : wseq α → wseq α
14 -/
15
16 /-- Weak sequences.
17
18 While the `seq` structure allows for lists which may not be finite,
19 a weak sequence also allows the computation of each element to
20 involve an indeterminate amount of computation, including possibly
21 an infinite loop. This is represented as a regular `seq` interspersed
22 with `none` elements to indicate that computation is ongoing.
23
24 This model is appropriate for Haskell style lazy lists, and is closed
25 under most interesting computation patterns on infinite lists,
26 but conversely it is difficult to extract elements from it. -/
27 def wseq (α) := seq (option α)
id └─┘ └────┘ ┴
src └─┘ └────┘
typ └─┘ └────┘ ┴
doc └─┘
28
29 namespace wseq
30 variables {α : Type u} {β : Type v} {γ : Type w}
31
32 /-- Turn a sequence into a weak sequence -/
33 def of_seq : seq α → wseq α := (<$>) some
id └─┘ ┴ └──┘ ┴ ┴ └──┘
src └─┘ └──┘ ┴ └──┘
typ └─┘ ┴ └──┘ ┴ ┴ └──┘
doc └─┘ └──┘
34
35 /-- Turn a list into a weak sequence -/
36 def of_list (l : list α) : wseq α := of_seq l
id └──┘ ┴ └──┘ ┴ └────┘ ┴
src └──┘ └──┘ └────┘
typ └──┘ ┴ └──┘ ┴ └────┘ ┴
doc └──┘ └────┘
37
38 /-- Turn a stream into a weak sequence -/
39 def of_stream (l : stream α) : wseq α := of_seq l
id └────┘ ┴ └──┘ ┴ └────┘ ┴
src └────┘ └──┘ └────┘
typ └────┘ ┴ └──┘ ┴ └────┘ ┴
doc └──┘ └────┘
40
41 instance coe_seq : has_coe (seq α) (wseq α) := ⟨of_seq⟩
id └─────┘ └─┘ ┴ └──┘ ┴ └────┘
src └─────┘ └─┘ └──┘ └────┘
typ └─────┘ └─┘ ┴ └──┘ ┴ └────┘
doc └─┘ └──┘ └────┘
42 instance coe_list : has_coe (list α) (wseq α) := ⟨of_list⟩
id └─────┘ └──┘ ┴ └──┘ ┴ └─────┘
src └─────┘ └──┘ └──┘ └─────┘
typ └─────┘ └──┘ ┴ └──┘ ┴ └─────┘
doc └──┘ └─────┘
43 instance coe_stream : has_coe (stream α) (wseq α) := ⟨of_stream⟩
id └─────┘ └────┘ ┴ └──┘ ┴ └───────┘
src └─────┘ └────┘ └──┘ └───────┘
typ └─────┘ └────┘ ┴ └──┘ ┴ └───────┘
doc └──┘ └───────┘
44
45 /-- The empty weak sequence -/
46 def nil : wseq α := seq.nil
id └──┘ ┴ └─────┘
src └──┘ └─────┘
typ └──┘ ┴ └─────┘
doc └──┘ └─────┘
47
48 instance : inhabited (wseq α) := ⟨nil⟩
id └───────┘ └──┘ ┴ └─┘
src └───────┘ └──┘ └─┘
typ └───────┘ └──┘ ┴ └─┘
doc └──┘ └─┘
49
50 /-- Prepend an element to a weak sequence -/
51 def cons (a : α) : wseq α → wseq α := seq.cons (some a)
id ┴ └──┘ ┴ └──┘ ┴ └──────┘ └──┘ ┴
src └──┘ └──┘ └──────┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴ └──────┘ └──┘ ┴
doc └──┘ └──┘ └──────┘
52
53 /-- Compute for one tick, without producing any elements -/
54 def think : wseq α → wseq α := seq.cons none
id └──┘ ┴ └──┘ ┴ └──────┘ └──┘
src └──┘ └──┘ └──────┘ └──┘
typ └──┘ ┴ └──┘ ┴ └──────┘ └──┘
doc └──┘ └──┘ └──────┘
55
56 /-- Destruct a weak sequence, to (eventually possibly) produce either
57 `none` for `nil` or `some (a, s)` if an element is produced. -/
58 def destruct : wseq α → computation (option (α × wseq α)) :=
id └──┘ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
src └──┘ └─────────┘ └────┘ ┴ └──┘
typ └──┘ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
doc └──┘ └─────────┘ └──┘
59 computation.corec (λs, match seq.destruct s with
id └───────────────┘ ┴ └──────────┘ ┴
src └───────────────┘ └──────────┘
typ └───────────────┘ ┴ └──────────┘ ┴
doc └───────────────┘ └──────────┘
60 | none := sum.inl none
id └──┘ └─────┘ └──┘
src └──┘ └─────┘ └──┘
typ └──┘ └─────┘ └──┘
61 | some (none, s') := sum.inr s'
id └──┘ ┴└──┘ └┘ └─────┘
src └──┘ ┴└──┘ └─────┘
typ └──┘ ┴└──┘ └┘ └─────┘
62 | some (some a, s') := sum.inl (some (a, s'))
id ┴└──┘ ┴ └┘ └─────┘ └──┘ ┴
src ┴└──┘ └─────┘ └──┘ ┴
typ ┴└──┘ ┴ └┘ └─────┘ └──┘ ┴
63 end)
64
65 def cases_on {C : wseq α → Sort v} (s : wseq α) (h1 : C nil)
id └──┘ ┴ └──┘ ┴ ┴ └─┘
src └──┘ └──┘ └─┘
typ └──┘ ┴ └──┘ ┴ ┴ └─┘
doc └──┘ └──┘ └─┘
66 (h2 : ∀ x s, C (cons x s)) (h3 : ∀ s, C (think s)) : C s :=
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └──┘ └───┘
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └──┘ └───┘
67 seq.cases_on s h1 (λ o, option.cases_on o h3 h2)
id └──────────┘ ┴ └┘ ┴ └─────────────┘ ┴ └┘ └┘
src └──────────┘ └─────────────┘
typ └──────────┘ ┴ └┘ ┴ └─────────────┘ ┴ └┘ └┘
68
69 protected def mem (a : α) (s : wseq α) := seq.mem (some a) s
id ┴ └──┘ ┴ └─────┘ └──┘ ┴ ┴
src └──┘ └─────┘ └──┘
typ ┴ └──┘ ┴ └─────┘ └──┘ ┴ ┴
doc └──┘
70
71 instance : has_mem α (wseq α) :=
id └─────┘ ┴ └──┘ ┴
src └─────┘ └──┘
typ └─────┘ ┴ └──┘ ┴
doc └──┘
72 ⟨wseq.mem⟩
id └──────┘
src └──────┘
typ └──────┘
73
74 theorem not_mem_nil (a : α) : a ∉ @nil α := seq.not_mem_nil a
id ┴ ┴ ┴ └─┘ ┴ └─────────────┘ ┴
src ┴ └─┘ └─────────────┘
typ ┴ ┴ ┴ └─┘ ┴ └─────────────┘ ┴
doc └─┘
75
76 /-- Get the head of a weak sequence. This involves a possibly
77 infinite computation. -/
78 def head (s : wseq α) : computation (option α) :=
id └──┘ ┴ └─────────┘ └────┘ ┴
src └──┘ └─────────┘ └────┘
typ └──┘ ┴ └─────────┘ └────┘ ┴
doc └──┘ └─────────┘
79 computation.map ((<$>) prod.fst) (destruct s)
id └─────────────┘ ┴ └──────┘ └──────┘ ┴
src └─────────────┘ ┴ └──────┘ └──────┘
typ └─────────────┘ ┴ └──────┘ └──────┘ ┴
doc └─────────────┘ └──────┘
80
81 /-- Encode a computation yielding a weak sequence into additional
82 `think` constructors in a weak sequence -/
83 def flatten : computation (wseq α) → wseq α :=
id └─────────┘ └──┘ ┴ └──┘ ┴
src └─────────┘ └──┘ └──┘
typ └─────────┘ └──┘ ┴ └──┘ ┴
doc └─────────┘ └──┘ └──┘
84 seq.corec (λc, match computation.destruct c with
id └───────┘ ┴ └──────────────────┘ ┴
src └───────┘ └──────────────────┘
typ └───────┘ ┴ └──────────────────┘ ┴
doc └───────┘ └──────────────────┘
85 | sum.inl s := seq.omap return (seq.destruct s)
id └─────┘ ┴ └──────┘ └────┘ └──────────┘
src └─────┘ └──────┘ └────┘ └──────────┘
typ └─────┘ ┴ └──────┘ └────┘ └──────────┘
doc └──────┘ └──────────┘
86 | sum.inr c' := some (none, c')
id └─────┘ └┘ └──┘ ┴└──┘
src └─────┘ └──┘ ┴└──┘
typ └─────┘ └┘ └──┘ ┴└──┘
87 end)
88
89 /-- Get the tail of a weak sequence. This doesn't need a `computation`
90 wrapper, unlike `head`, because `flatten` allows us to hide this
91 in the construction of the weak sequence itself. -/
92 def tail (s : wseq α) : wseq α :=
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
93 flatten $ (λo, option.rec_on o nil prod.snd) <$> destruct s
id └─────┘ ┴ └───────────┘ ┴ └─┘ └──────┘ └─┘ └──────┘ ┴
src └─────┘ └───────────┘ └─┘ └──────┘ └─┘ └──────┘
typ └─────┘ ┴ └───────────┘ ┴ └─┘ └──────┘ └─┘ └──────┘ ┴
doc └─────┘ └─┘ └──────┘
94
95 /-- drop the first `n` elements from `s`. -/
96 def drop (s : wseq α) : ℕ → wseq α
id └──┘ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
97 | 0 := s
id ┴
typ ┴
98 | (n+1) := tail (drop n)
id ┴┴ └──┘ └──┘
src ┴ └──┘
typ ┴┴ └──┘ └──┘
doc └──┘
99 attribute [simp] drop
id └──┘
src └──┘
typ └──┘
doc └──┘ └──┘
100
101 /-- Get the nth element of `s`. -/
102 def nth (s : wseq α) (n : ℕ) : computation (option α) := head (drop s n)
id └──┘ ┴ ┴ └─────────┘ └────┘ ┴ └──┘ └──┘ ┴ ┴
src └──┘ ┴ └─────────┘ └────┘ └──┘ └──┘
typ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ └──┘ └──┘ ┴ ┴
doc └──┘ └─────────┘ └──┘ └──┘
103
104 /-- Convert `s` to a list (if it is finite and completes in finite time). -/
105 def to_list (s : wseq α) : computation (list α) :=
id └──┘ ┴ └─────────┘ └──┘ ┴
src └──┘ └─────────┘ └──┘
typ └──┘ ┴ └─────────┘ └──┘ ┴
doc └──┘ └─────────┘
106 @computation.corec (list α) (list α × wseq α) (λ⟨l, s⟩,
id └───────────────┘ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └───────────────┘ └──┘ └──┘ ┴ └──┘
typ └───────────────┘ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └───────────────┘ └──┘
107 match seq.destruct s with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
108 | none := sum.inl l.reverse
id └──┘ └─────┘ └──────┘
src └──┘ └─────┘ └──────┘
typ └──┘ └─────┘ └──────┘
109 | some (none, s') := sum.inr (l, s')
id └──┘ ┴└──┘ └┘ └─────┘ ┴
src └──┘ ┴└──┘ └─────┘ ┴
typ └──┘ ┴└──┘ └┘ └─────┘ ┴
110 | some (some a, s') := sum.inr (a::l, s')
id ┴└──┘ ┴ └┘ └─────┘ ┴ └┘
src ┴└──┘ └─────┘ ┴ └┘
typ ┴└──┘ ┴ └┘ └─────┘ ┴ └┘
111 end) ([], s)
id ┴└┘ ┴
src ┴└┘
typ ┴└┘ ┴
112
113 /-- Get the length of `s` (if it is finite and completes in finite time). -/
114 def length (s : wseq α) : computation ℕ :=
id └──┘ ┴ └─────────┘ ┴
src └──┘ └─────────┘ ┴
typ └──┘ ┴ └─────────┘ ┴
doc └──┘ └─────────┘
115 @computation.corec ℕ (ℕ × wseq α) (λ⟨n, s⟩,
id └───────────────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └───────────────┘ ┴ ┴ ┴ └──┘
typ └───────────────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └───────────────┘ └──┘
116 match seq.destruct s with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
117 | none := sum.inl n
id └──┘ └─────┘
src └──┘ └─────┘
typ └──┘ └─────┘
118 | some (none, s') := sum.inr (n, s')
id └──┘ ┴└──┘ └┘ └─────┘ ┴
src └──┘ ┴└──┘ └─────┘ ┴
typ └──┘ ┴└──┘ └┘ └─────┘ ┴
119 | some (some a, s') := sum.inr (n+1, s')
id ┴└──┘ └┘ └─────┘ ┴ ┴
src ┴└──┘ └─────┘ ┴ ┴
typ ┴└──┘ └┘ └─────┘ ┴ ┴
120 end) (0, s)
id ┴ ┴
src ┴
typ ┴ ┴
121
122 /-- A weak sequence is finite if `to_list s` terminates. Equivalently,
123 it is a finite number of `think` and `cons` applied to `nil`. -/
124 @[class] def is_finite (s : wseq α) : Prop := (to_list s).terminates
id └──┘ ┴ └─────┘ ┴ └────────┘
src └──┘ └─────┘ └────────┘
typ └──┘ ┴ └─────┘ ┴ └────────┘
doc └──┘ └─────┘ └────────┘
125
126 instance to_list_terminates (s : wseq α) [h : is_finite s] : (to_list s).terminates := h
id └──┘ ┴ └───────┘ ┴ └─────┘ ┴ └────────┘ ┴
src └──┘ └───────┘ └─────┘ └────────┘
typ └──┘ ┴ └───────┘ ┴ └─────┘ ┴ └────────┘ ┴
doc └──┘ └───────┘ └─────┘ └────────┘
127
128 /-- Get the list corresponding to a finite weak sequence. -/
129 def get (s : wseq α) [is_finite s] : list α := (to_list s).get
id └──┘ ┴ └───────┘ ┴ └──┘ ┴ └─────┘ ┴ └─┘
src └──┘ └───────┘ └──┘ └─────┘ └─┘
typ └──┘ ┴ └───────┘ ┴ └──┘ ┴ └─────┘ ┴ └─┘
doc └──┘ └───────┘ └─────┘ └─┘
130
131 /-- A weak sequence is *productive* if it never stalls forever - there are
132 always a finite number of `think`s between `cons` constructors.
133 The sequence itself is allowed to be infinite though. -/
134 @[class] def productive (s : wseq α) : Prop := ∀ n, (nth s n).terminates
id └──┘ ┴ ┴ └─┘ ┴ ┴ └────────┘
src └──┘ └─┘ └────────┘
typ └──┘ ┴ ┴ └─┘ ┴ ┴ └────────┘
doc └──┘ └─┘ └────────┘
135
136 instance nth_terminates (s : wseq α) [h : productive s] : ∀ n, (nth s n).terminates := h
id └──┘ ┴ └────────┘ ┴ ┴ └─┘ ┴ ┴ └────────┘ ┴
src └──┘ └────────┘ └─┘ └────────┘
typ └──┘ ┴ └────────┘ ┴ ┴ └─┘ ┴ ┴ └────────┘ ┴
doc └──┘ └────────┘ └─┘ └────────┘
137
138 instance head_terminates (s : wseq α) [h : productive s] : (head s).terminates := h 0
id └──┘ ┴ └────────┘ ┴ └──┘ ┴ └────────┘ ┴
src └──┘ └────────┘ └──┘ └────────┘
typ └──┘ ┴ └────────┘ ┴ └──┘ ┴ └────────┘ ┴
doc └──┘ └────────┘ └──┘ └────────┘
139
140 /-- Replace the `n`th element of `s` with `a`. -/
141 def update_nth (s : wseq α) (n : ℕ) (a : α) : wseq α :=
id └──┘ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
142 @seq.corec (option α) (ℕ × wseq α) (λ⟨n, s⟩,
id └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └───────┘ └────┘ ┴ ┴ └──┘
typ └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └───────┘ └──┘
143 match seq.destruct s, n with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
144 | none, n := none
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
145 | some (none, s'), n := some (none, n, s')
id └──┘ ┴└──┘ └┘ ┴ └──┘ ┴└──┘
src └──┘ ┴└──┘ └──┘ ┴└──┘
typ └──┘ ┴└──┘ └┘ ┴ └──┘ ┴└──┘
146 | some (some a', s'), 0 := some (some a', 0, s')
id ┴└──┘ └┘ └┘ └──┘ ┴└──┘
src ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ └┘ └┘ └──┘ ┴└──┘
147 | some (some a', s'), 1 := some (some a, 0, s')
id ┴└──┘ └┘ └──┘ ┴└──┘ ┴
src ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ └┘ └──┘ ┴└──┘ ┴
148 | some (some a', s'), (n+2) := some (some a', n+1, s')
id ┴└──┘ └┘ └┘ ┴┴ └──┘ ┴└──┘ ┴
src ┴└──┘ ┴ └──┘ ┴└──┘ ┴
typ ┴└──┘ └┘ └┘ ┴┴ └──┘ ┴└──┘ ┴
149 end) (n+1, s)
id ┴┴┴ ┴
src ┴ ┴
typ ┴┴┴ ┴
150
151 /-- Remove the `n`th element of `s`. -/
152 def remove_nth (s : wseq α) (n : ℕ) : wseq α :=
id └──┘ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
153 @seq.corec (option α) (ℕ × wseq α) (λ⟨n, s⟩,
id └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └───────┘ └────┘ ┴ ┴ └──┘
typ └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └───────┘ └──┘
154 match seq.destruct s, n with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
155 | none, n := none
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
156 | some (none, s'), n := some (none, n, s')
id └──┘ ┴└──┘ └┘ ┴ └──┘ ┴└──┘
src └──┘ ┴└──┘ └──┘ ┴└──┘
typ └──┘ ┴└──┘ └┘ ┴ └──┘ ┴└──┘
157 | some (some a', s'), 0 := some (some a', 0, s')
id ┴└──┘ └┘ └┘ └──┘ ┴└──┘
src ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ └┘ └┘ └──┘ ┴└──┘
158 | some (some a', s'), 1 := some (none, 0, s')
id ┴└──┘ └┘ └──┘ ┴└──┘
src ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ └┘ └──┘ ┴└──┘
159 | some (some a', s'), (n+2) := some (some a', n+1, s')
id ┴└──┘ └┘ └┘ ┴┴ └──┘ ┴└──┘ ┴
src ┴└──┘ ┴ └──┘ ┴└──┘ ┴
typ ┴└──┘ └┘ └┘ ┴┴ └──┘ ┴└──┘ ┴
160 end) (n+1, s)
id ┴┴┴ ┴
src ┴ ┴
typ ┴┴┴ ┴
161
162 /-- Map the elements of `s` over `f`, removing any values that yield `none`. -/
163 def filter_map (f : α → option β) : wseq α → wseq β :=
id ┴ └────┘ ┴ └──┘ ┴ └──┘ ┴
src └────┘ └──┘ └──┘
typ ┴ └────┘ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
164 seq.corec (λs, match seq.destruct s with
id └───────┘ ┴ └──────────┘ ┴
src └───────┘ └──────────┘
typ └───────┘ ┴ └──────────┘ ┴
doc └───────┘ └──────────┘
165 | none := none
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
166 | some (none, s') := some (none, s')
id └──┘ ┴└──┘ └┘ └──┘ ┴└──┘
src └──┘ ┴└──┘ └──┘ ┴└──┘
typ └──┘ ┴└──┘ └┘ └──┘ ┴└──┘
167 | some (some a, s') := some (f a, s')
id ┴└──┘ ┴ └┘ └──┘ ┴┴
src ┴└──┘ └──┘ ┴
typ ┴└──┘ ┴ └┘ └──┘ ┴┴
168 end)
169
170 /-- Select the elements of `s` that satisfy `p`. -/
171 def filter (p : α → Prop) [decidable_pred p] : wseq α → wseq α :=
id ┴ └────────────┘ ┴ └──┘ ┴ └──┘ ┴
src └────────────┘ └──┘ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
172 filter_map (λa, if p a then some a else none)
id └────────┘ ┴ ┴ ┴ └──┘ ┴ └──┘
src └────────┘ └──┘ └──┘
typ └────────┘ ┴ ┴ ┴ └──┘ ┴ └──┘
doc └────────┘
173
174 -- example of infinite list manipulations
175 /-- Get the first element of `s` satisfying `p`. -/
176 def find (p : α → Prop) [decidable_pred p] (s : wseq α) : computation (option α) :=
id ┴ └────────────┘ ┴ └──┘ ┴ └─────────┘ └────┘ ┴
src └────────────┘ └──┘ └─────────┘ └────┘
typ ┴ └────────────┘ ┴ └──┘ ┴ └─────────┘ └────┘ ┴
doc └──┘ └─────────┘
177 head $ filter p s
id └──┘ └────┘ ┴ ┴
src └──┘ └────┘
typ └──┘ └────┘ ┴ ┴
doc └──┘ └────┘
178
179 /-- Zip a function over two weak sequences -/
180 def zip_with (f : α → β → γ) (s1 : wseq α) (s2 : wseq β) : wseq γ :=
id ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘
181 @seq.corec (option γ) (wseq α × wseq β) (λ⟨s1, s2⟩,
id └───────┘ └────┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴└┘ └┘
src └───────┘ └────┘ └──┘ ┴ └──┘
typ └───────┘ └────┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴└┘ └┘
doc └───────┘ └──┘ └──┘
182 match seq.destruct s1, seq.destruct s2 with
id └──────────┘ └──────────┘
src └──────────┘ └──────────┘
typ └──────────┘ └──────────┘
doc └──────────┘ └──────────┘
183 | some (none, s1'), some (none, s2') := some (none, s1', s2')
id ┴ └─┘ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
src ┴ └──┘ ┴└──┘ └──┘ ┴└──┘
typ ┴ └─┘ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
184 | some (some a1, s1'), some (none, s2') := some (none, s1, s2')
id ┴ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
src ┴ └──┘ ┴└──┘ └──┘ ┴└──┘
typ ┴ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
185 | some (none, s1'), some (some a2, s2') := some (none, s1', s2)
id ┴└──┘ └─┘ ┴└──┘ └──┘ ┴└──┘
src ┴└──┘ ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ └─┘ ┴└──┘ └──┘ ┴└──┘
186 | some (some a1, s1'), some (some a2, s2') := some (some (f a1 a2), s1', s2')
id ┴ └┘ └─┘ ┴└──┘ └┘ └─┘ └──┘ ┴└──┘ ┴
src ┴ ┴└──┘ └──┘ ┴└──┘
typ ┴ └┘ └─┘ ┴└──┘ └┘ └─┘ └──┘ ┴└──┘ ┴
187 | _, _ := none
id └──┘
src └──┘
typ └──┘
188 end) (s1, s2)
id ┴└┘ └┘
src ┴
typ ┴└┘ └┘
189
190 /-- Zip two weak sequences into a single sequence of pairs -/
191 def zip : wseq α → wseq β → wseq (α × β) := zip_with prod.mk
id └──┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──────┘ └─────┘
src └──┘ └──┘ └──┘ ┴ └──────┘ └─────┘
typ └──┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──────┘ └─────┘
doc └──┘ └──┘ └──┘ └──────┘
192
193 /-- Get the list of indexes of elements of `s` satisfying `p` -/
194 def find_indexes (p : α → Prop) [decidable_pred p] (s : wseq α) : wseq ℕ :=
id ┴ └────────────┘ ┴ └──┘ ┴ └──┘ ┴
src └────────────┘ └──┘ └──┘ ┴
typ ┴ └────────────┘ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
195 (zip s (stream.nats : wseq ℕ)).filter_map
id └─┘ ┴ └─────────┘ └──┘ ┴ └────────┘
src └─┘ └─────────┘ └──┘ ┴ └────────┘
typ └─┘ ┴ └─────────┘ └──┘ ┴ └────────┘
doc └─┘ └──┘ └────────┘
196 (λ ⟨a, n⟩, if p a then some n else none)
id ┴┴ ┴ ┴ └──┘ └──┘
src └──┘ └──┘
typ ┴┴ ┴ ┴ └──┘ └──┘
197
198 /-- Get the index of the first element of `s` satisfying `p` -/
199 def find_index (p : α → Prop) [decidable_pred p] (s : wseq α) : computation ℕ :=
id ┴ └────────────┘ ┴ └──┘ ┴ └─────────┘ ┴
src └────────────┘ └──┘ └─────────┘ ┴
typ ┴ └────────────┘ ┴ └──┘ ┴ └─────────┘ ┴
doc └──┘ └─────────┘
200 (λ o, option.get_or_else o 0) <$> head (find_indexes p s)
id ┴ └────────────────┘ ┴ └─┘ └──┘ └──────────┘ ┴ ┴
src └────────────────┘ └─┘ └──┘ └──────────┘
typ ┴ └────────────────┘ ┴ └─┘ └──┘ └──────────┘ ┴ ┴
doc └──┘ └──────────┘
201
202 /-- Get the index of the first occurrence of `a` in `s` -/
203 def index_of [decidable_eq α] (a : α) : wseq α → computation ℕ := find_index (eq a)
id └──────────┘ ┴ ┴ └──┘ ┴ └─────────┘ ┴ └────────┘ └┘ ┴
src └──────────┘ └──┘ └─────────┘ ┴ └────────┘ └┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └─────────┘ ┴ └────────┘ └┘ ┴
doc └──┘ └─────────┘ └────────┘
204
205 /-- Get the indexes of occurrences of `a` in `s` -/
206 def indexes_of [decidable_eq α] (a : α) : wseq α → wseq ℕ := find_indexes (eq a)
id └──────────┘ ┴ ┴ └──┘ ┴ └──┘ ┴ └──────────┘ └┘ ┴
src └──────────┘ └──┘ └──┘ ┴ └──────────┘ └┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └──┘ ┴ └──────────┘ └┘ ┴
doc └──┘ └──┘ └──────────┘
207
208 /-- `union s1 s2` is a weak sequence which interleaves `s1` and `s2` in
209 some order (nondeterministically). -/
210 def union (s1 s2 : wseq α) : wseq α :=
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
211 @seq.corec (option α) (wseq α × wseq α) (λ⟨s1, s2⟩,
id └───────┘ └────┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴└┘ └┘
src └───────┘ └────┘ └──┘ ┴ └──┘
typ └───────┘ └────┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴└┘ └┘
doc └───────┘ └──┘ └──┘
212 match seq.destruct s1, seq.destruct s2 with
id └──────────┘ └──────────┘
src └──────────┘ └──────────┘
typ └──────────┘ └──────────┘
doc └──────────┘ └──────────┘
213 | none, none := none
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
214 | some (a1, s1'), none := some (a1, s1', nil)
id └──┘ ┴└┘ └─┘ └──┘ └──┘ ┴ └─┘
src └──┘ ┴ └──┘ └──┘ ┴ └─┘
typ └──┘ ┴└┘ └─┘ └──┘ └──┘ ┴ └─┘
doc └─┘
215 | none, some (a2, s2') := some (a2, nil, s2')
id └──┘ └──┘ ┴└┘ └─┘ └──┘ ┴ └─┘
src └──┘ └──┘ ┴ └──┘ ┴ └─┘
typ └──┘ └──┘ ┴└┘ └─┘ └──┘ ┴ └─┘
doc └─┘
216 | some (none, s1'), some (none, s2') := some (none, s1', s2')
id ┴ └─┘ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
src ┴ └──┘ ┴└──┘ └──┘ ┴└──┘
typ ┴ └─┘ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
217 | some (some a1, s1'), some (none, s2') := some (some a1, s1', s2')
id ┴ └┘ └─┘ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
src ┴ └──┘ ┴└──┘ └──┘ ┴└──┘
typ ┴ └┘ └─┘ └──┘ ┴└──┘ └─┘ └──┘ ┴└──┘
218 | some (none, s1'), some (some a2, s2') := some (some a2, s1', s2')
id ┴└──┘ └─┘ ┴└──┘ └┘ └─┘ └──┘ ┴└──┘
src ┴└──┘ ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ └─┘ ┴└──┘ └┘ └─┘ └──┘ ┴└──┘
219 | some (some a1, s1'), some (some a2, s2') := some (some a1, cons a2 s1', s2')
id ┴ └┘ └─┘ ┴└──┘ └┘ └─┘ └──┘ ┴└──┘ └──┘
src ┴ ┴└──┘ └──┘ ┴└──┘ └──┘
typ ┴ └┘ └─┘ ┴└──┘ └┘ └─┘ └──┘ ┴└──┘ └──┘
doc └──┘
220 end) (s1, s2)
id ┴└┘ └┘
src ┴
typ ┴└┘ └┘
221
222 /-- Returns `tt` if `s` is `nil` and `ff` if `s` has an element -/
223 def is_empty (s : wseq α) : computation bool :=
id └──┘ ┴ └─────────┘ └──┘
src └──┘ └─────────┘ └──┘
typ └──┘ ┴ └─────────┘ └──┘
doc └──┘ └─────────┘
224 computation.map option.is_none $ head s
id └─────────────┘ └────────────┘ └──┘ ┴
src └─────────────┘ └────────────┘ └──┘
typ └─────────────┘ └────────────┘ └──┘ ┴
doc └─────────────┘ └──┘
225
226 /-- Calculate one step of computation -/
227 def compute (s : wseq α) : wseq α :=
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
228 match seq.destruct s with
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
doc └──────────┘
229 | some (none, s') := s'
id └──┘ ┴└──┘ └┘
src └──┘ ┴└──┘
typ └──┘ ┴└──┘ └┘
230 | _ := s
id ┴
typ ┴
231 end
232
233 /-- Get the first `n` elements of a weak sequence -/
234 def take (s : wseq α) (n : ℕ) : wseq α :=
id └──┘ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
235 @seq.corec (option α) (ℕ × wseq α) (λ⟨n, s⟩,
id └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └───────┘ └────┘ ┴ ┴ └──┘
typ └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └───────┘ └──┘
236 match n, seq.destruct s with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
237 | 0, _ := none
id └──┘
src └──┘
typ └──┘
238 | m+1, none := none
id ┴ └──┘ └──┘
src ┴ └──┘ └──┘
typ ┴ └──┘ └──┘
239 | m+1, some (none, s') := some (none, m+1, s')
id ┴┴ └──┘ ┴└──┘ └┘ └──┘ ┴└──┘ ┴
src ┴ └──┘ ┴└──┘ └──┘ ┴└──┘ ┴
typ ┴┴ └──┘ ┴└──┘ └┘ └──┘ ┴└──┘ ┴
240 | m+1, some (some a, s') := some (some a, m, s')
id ┴┴ ┴└──┘ ┴ └┘ └──┘ ┴└──┘
src ┴ ┴└──┘ └──┘ ┴└──┘
typ ┴┴ ┴└──┘ ┴ └┘ └──┘ ┴└──┘
241 end) (n, s)
id ┴┴ ┴
src ┴
typ ┴┴ ┴
242
243 /-- Split the sequence at position `n` into a finite initial segment
244 and the weak sequence tail -/
245 def split_at (s : wseq α) (n : ℕ) : computation (list α × wseq α) :=
id └──┘ ┴ ┴ └─────────┘ └──┘ ┴ ┴ └──┘ ┴
src └──┘ ┴ └─────────┘ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └─────────┘ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └─────────┘ └──┘
246 @computation.corec (list α × wseq α) (ℕ × list α × wseq α) (λ⟨n, l, s⟩,
id └───────────────┘ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴┴ ┴ ┴
src └───────────────┘ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ └──┘
typ └───────────────┘ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴┴ ┴ ┴
doc └───────────────┘ └──┘ └──┘
247 match n, seq.destruct s with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
248 | 0, _ := sum.inl (l.reverse, s)
id └─────┘ ┴ └──────┘
src └─────┘ ┴ └──────┘
typ └─────┘ ┴ └──────┘
249 | m+1, none := sum.inl (l.reverse, s)
id ┴ └──┘ └─────┘ ┴ └──────┘
src ┴ └──┘ └─────┘ ┴ └──────┘
typ ┴ └──┘ └─────┘ ┴ └──────┘
250 | m+1, some (none, s') := sum.inr (n, l, s')
id ┴ └──┘ ┴└──┘ └┘ └─────┘ ┴
src ┴ └──┘ ┴└──┘ └─────┘ ┴
typ ┴ └──┘ ┴└──┘ └┘ └─────┘ ┴
251 | m+1, some (some a, s') := sum.inr (m, a::l, s')
id ┴┴ ┴└──┘ ┴ └┘ └─────┘ ┴ └┘
src ┴ ┴└──┘ └─────┘ ┴ └┘
typ ┴┴ ┴└──┘ ┴ └┘ └─────┘ ┴ └┘
252 end) (n, [], s)
id ┴┴ └┘ ┴
src ┴ └┘
typ ┴┴ └┘ ┴
253
254 /-- Returns `tt` if any element of `s` satisfies `p` -/
255 def any (s : wseq α) (p : α → bool) : computation bool :=
id └──┘ ┴ ┴ └──┘ └─────────┘ └──┘
src └──┘ └──┘ └─────────┘ └──┘
typ └──┘ ┴ ┴ └──┘ └─────────┘ └──┘
doc └──┘ └─────────┘
256 computation.corec (λs : wseq α,
id └───────────────┘ └──┘ ┴
src └───────────────┘ └──┘
typ └───────────────┘ └──┘ ┴
doc └───────────────┘ └──┘
257 match seq.destruct s with
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
doc └──────────┘
258 | none := sum.inl ff
id └──┘ └─────┘ └┘
src └──┘ └─────┘ └┘
typ └──┘ └─────┘ └┘
259 | some (none, s') := sum.inr s'
id └──┘ ┴└──┘ └┘ └─────┘
src └──┘ ┴└──┘ └─────┘
typ └──┘ ┴└──┘ └┘ └─────┘
260 | some (some a, s') := if p a then sum.inl tt else sum.inr s'
id ┴└──┘ ┴ └┘ ┴ └─────┘ └┘ └─────┘
src ┴└──┘ └─────┘ └┘ └─────┘
typ ┴└──┘ ┴ └┘ ┴ └─────┘ └┘ └─────┘
261 end) s
id ┴
typ ┴
262
263 /-- Returns `tt` if every element of `s` satisfies `p` -/
264 def all (s : wseq α) (p : α → bool) : computation bool :=
id └──┘ ┴ ┴ └──┘ └─────────┘ └──┘
src └──┘ └──┘ └─────────┘ └──┘
typ └──┘ ┴ ┴ └──┘ └─────────┘ └──┘
doc └──┘ └─────────┘
265 computation.corec (λs : wseq α,
id └───────────────┘ └──┘ ┴
src └───────────────┘ └──┘
typ └───────────────┘ └──┘ ┴
doc └───────────────┘ └──┘
266 match seq.destruct s with
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
doc └──────────┘
267 | none := sum.inl tt
id └──┘ └─────┘ └┘
src └──┘ └─────┘ └┘
typ └──┘ └─────┘ └┘
268 | some (none, s') := sum.inr s'
id └──┘ ┴└──┘ └┘ └─────┘
src └──┘ ┴└──┘ └─────┘
typ └──┘ ┴└──┘ └┘ └─────┘
269 | some (some a, s') := if p a then sum.inr s' else sum.inl ff
id ┴└──┘ ┴ └┘ ┴ └─────┘ └─────┘ └┘
src ┴└──┘ └─────┘ └─────┘ └┘
typ ┴└──┘ ┴ └┘ ┴ └─────┘ └─────┘ └┘
270 end) s
id ┴
typ ┴
271
272 /-- Apply a function to the elements of the sequence to produce a sequence
273 of partial results. (There is no `scanr` because this would require
274 working from the end of the sequence, which may not exist.) -/
275 def scanl (f : α → β → α) (a : α) (s : wseq β) : wseq α :=
id ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
276 cons a $ @seq.corec (option α) (α × wseq β) (λ⟨a, s⟩,
id └──┘ ┴ └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └──┘ └───────┘ └────┘ ┴ └──┘
typ └──┘ ┴ └───────┘ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └──┘ └───────┘ └──┘
277 match seq.destruct s with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
278 | none := none
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
279 | some (none, s') := some (none, a, s')
id └──┘ ┴└──┘ └┘ └──┘ ┴└──┘
src └──┘ ┴└──┘ └──┘ ┴└──┘
typ └──┘ ┴└──┘ └┘ └──┘ ┴└──┘
280 | some (some b, s') := let a' := f a b in some (some a', a', s')
id ┴└──┘ ┴ └┘ └┘ ┴ └──┘ ┴└──┘ └┘ └┘
src ┴└──┘ └──┘ ┴└──┘
typ ┴└──┘ ┴ └┘ └┘ ┴ └──┘ ┴└──┘ └┘ └┘
281 end) (a, s)
id ┴┴ ┴
src ┴
typ ┴┴ ┴
282
283 /-- Get the weak sequence of initial segments of the input sequence -/
284 def inits (s : wseq α) : wseq (list α) :=
id └──┘ ┴ └──┘ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ ┴ └──┘ └──┘ ┴
doc └──┘ └──┘
285 cons [] $ @seq.corec (option (list α)) (dlist α × wseq α) (λ ⟨l, s⟩,
id └──┘ └┘ └───────┘ └────┘ └──┘ ┴ └───┘ ┴ ┴ └──┘ ┴ ┴┴ ┴
src └──┘ └┘ └───────┘ └────┘ └──┘ └───┘ ┴ └──┘
typ └──┘ └┘ └───────┘ └────┘ └──┘ ┴ └───┘ ┴ ┴ └──┘ ┴ ┴┴ ┴
doc └──┘ └───────┘ └───┘ └──┘
286 match seq.destruct s with
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──────────┘
287 | none := none
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
288 | some (none, s') := some (none, l, s')
id └──┘ ┴└──┘ └┘ └──┘ ┴└──┘
src └──┘ ┴└──┘ └──┘ ┴└──┘
typ └──┘ ┴└──┘ └┘ └──┘ ┴└──┘
289 | some (some a, s') := let l' := l.concat a in
id ┴└──┘ ┴ └┘ └┘ └─────┘
src ┴└──┘ └─────┘
typ ┴└──┘ ┴ └┘ └┘ └─────┘
doc └─────┘
290 some (some l'.to_list, l', s')
id └──┘ ┴└──┘ └┘└──────┘ └┘
src └──┘ ┴└──┘ └──────┘
typ └──┘ ┴└──┘ └┘└──────┘ └┘
doc └──────┘
291 end) (dlist.empty, s)
id ┴└─────────┘ ┴
src ┴└─────────┘
typ ┴└─────────┘ ┴
doc └─────────┘
292
293 /-- Like take, but does not wait for a result. Calculates `n` steps of
294 computation and returns the sequence computed so far -/
295 def collect (s : wseq α) (n : ℕ) : list α :=
id └──┘ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └──┘ ┴
doc └──┘
296 (seq.take n s).filter_map id
id └──────┘ ┴ ┴ └────────┘ └┘
src └──────┘ └────────┘ └┘
typ └──────┘ ┴ ┴ └────────┘ └┘
doc └──────┘
297
298 /-- Append two weak sequences. As with `seq.append`, this may not use
299 the second sequence if the first one takes forever to compute -/
300 def append : wseq α → wseq α → wseq α := seq.append
id └──┘ ┴ └──┘ ┴ └──┘ ┴ └────────┘
src └──┘ └──┘ └──┘ └────────┘
typ └──┘ ┴ └──┘ ┴ └──┘ ┴ └────────┘
doc └──┘ └──┘ └──┘ └────────┘
301
302 /-- Map a function over a weak sequence -/
303 def map (f : α → β) : wseq α → wseq β := seq.map (option.map f)
id ┴ ┴ └──┘ ┴ └──┘ ┴ └─────┘ └────────┘ ┴
src └──┘ └──┘ └─────┘ └────────┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴ └─────┘ └────────┘ ┴
doc └──┘ └──┘ └─────┘
304
305 /-- Flatten a sequence of weak sequences. (Note that this allows
306 empty sequences, unlike `seq.join`.) -/
307 def join (S : wseq (wseq α)) : wseq α :=
id └──┘ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘
308 seq.join ((λo : option (wseq α), match o with
id └──────┘ └────┘ └──┘ ┴ ┴
src └──────┘ └────┘ └──┘
typ └──────┘ └────┘ └──┘ ┴ ┴
doc └──────┘ └──┘
309 | none := seq1.ret none
id └──┘ └──────┘ └──┘
src └──┘ └──────┘ └──┘
typ └──┘ └──────┘ └──┘
doc └──────┘
310 | some s := (none, s)
id └──┘ ┴ ┴└──┘
src └──┘ ┴└──┘
typ └──┘ ┴ ┴└──┘
311 end) <$> S)
id └─┘ ┴
src └─┘
typ └─┘ ┴
312
313 /-- Monadic bind operator for weak sequences -/
314 def bind (s : wseq α) (f : α → wseq β) : wseq β :=
id └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘
315 join (map f s)
id └──┘ └─┘ ┴ ┴
src └──┘ └─┘
typ └──┘ └─┘ ┴ ┴
doc └──┘ └─┘
316
317 @[simp] def lift_rel_o (R : α → β → Prop) (C : wseq α → wseq β → Prop) :
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘
318 option (α × wseq α) → option (β × wseq β) → Prop
id └────┘ ┴ ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ └──┘ ┴
src └────┘ ┴ └──┘ └────┘ ┴ └──┘
typ └────┘ ┴ ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
319 | none none := true
id └──┘ └──┘
src └──┘ └──┘
typ └──┘ └──┘
320 | (some (a, s)) (some (b, t)) := R a b ∧ C s t
id ┴┴ ┴ └──┘ ┴┴ ┴ ┴ ┴ ┴
src ┴ └──┘ ┴ ┴
typ ┴┴ ┴ └──┘ ┴┴ ┴ ┴ ┴ ┴
321 | _ _ := false
id └───┘
src └───┘
typ └───┘
322
323 theorem lift_rel_o.imp {R S : α → β → Prop} {C D : wseq α → wseq β → Prop}
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
324 (H1 : ∀ a b, R a b → S a b) (H2 : ∀ s t, C s t → D s t) :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
325 ∀ {o p}, lift_rel_o R C o p → lift_rel_o S D o p
id ┴┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
src └────────┘ └────────┘
typ ┴┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
326 | none none h := trivial
id └──┘ └─────┘
src └──┘ └─────┘
typ └──┘ └─────┘
327 | (some (a, s)) (some (b, t)) h := and.imp (H1 _ _) (H2 _ _) h
id ┴ └──┘ ┴ ┴ └─────┘ └┘ └┘
src ┴ └──┘ ┴ └─────┘
typ ┴ └──┘ ┴ ┴ └─────┘ └┘ └┘
328 | none (some _) h := false.elim h
id └──┘ └──┘ ┴ └────────┘
src └──┘ └──┘ └────────┘
typ └──┘ └──┘ ┴ └────────┘
329 | (some (_, _)) none h := false.elim h
id └──┘ ┴ └──┘ ┴ └────────┘
src └──┘ ┴ └──┘ └────────┘
typ └──┘ ┴ └──┘ ┴ └────────┘
330
331 theorem lift_rel_o.imp_right (R : α → β → Prop) {C D : wseq α → wseq β → Prop}
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
332 (H : ∀ s t, C s t → D s t) {o p} : lift_rel_o R C o p → lift_rel_o R D o p :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
src └────────┘ └────────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
333 lift_rel_o.imp (λ _ _, id) H
id └────────────┘ ┴ ┴ └┘ ┴
src └────────────┘ └┘
typ └────────────┘ ┴ ┴ └┘ ┴
334
335 @[simp] def bisim_o (R : wseq α → wseq α → Prop) :
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘
336 option (α × wseq α) → option (α × wseq α) → Prop := lift_rel_o (=) R
id └────┘ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └──┘ ┴ └────────┘ ┴ ┴
src └────┘ ┴ └──┘ └────┘ ┴ └──┘ └────────┘ ┴
typ └────┘ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └──┘ ┴ └────────┘ ┴ ┴
doc └──┘ └──┘
337
338 theorem bisim_o.imp {R S : wseq α → wseq α → Prop} (H : ∀ s t, R s t → S s t) {o p} :
id └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘
339 bisim_o R o p → bisim_o S o p :=
id └─────┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
src └─────┘ └─────┘
typ └─────┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
340 lift_rel_o.imp_right _ H
id └──────────────────┘ ┴
src └──────────────────┘
typ └──────────────────┘ ┴
341
342 /-- Two weak sequences are `lift_rel R` related if they are either both empty,
343 or they are both nonempty and the heads are `R` related and the tails are
344 `lift_rel R` related. (This is a coinductive definition.) -/
345 def lift_rel (R : α → β → Prop) (s : wseq α) (t : wseq β) : Prop :=
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
346 ∃ C : wseq α → wseq β → Prop, C s t ∧
id ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └──┘ └──┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘
347 ∀ {s t}, C s t → computation.lift_rel (lift_rel_o R C) (destruct s) (destruct t)
id ┴ ┴ ┴ ┴ ┴ └──────────────────┘ └────────┘ ┴ ┴ └──────┘ ┴ └──────┘ ┴
src └──────────────────┘ └────────┘ └──────┘ └──────┘
typ ┴ ┴ ┴ ┴ ┴ └──────────────────┘ └────────┘ ┴ ┴ └──────┘ ┴ └──────┘ ┴
doc └──────────────────┘ └──────┘ └──────┘
348
349 /-- If two sequences are equivalent, then they have the same values and
350 the same computational behavior (i.e. if one loops forever then so does
351 the other), although they may differ in the number of `think`s needed to
352 arrive at the answer. -/
353 def equiv : wseq α → wseq α → Prop := lift_rel (=)
id └──┘ ┴ └──┘ ┴ └──────┘ ┴
src └──┘ └──┘ └──────┘ ┴
typ └──┘ ┴ └──┘ ┴ └──────┘ ┴
doc └──┘ └──┘ └──────┘
354
355 theorem lift_rel_destruct {R : α → β → Prop} {s : wseq α} {t : wseq β} :
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
356 lift_rel R s t →
id └──────┘ ┴ ┴ ┴ ┴
src └──────┘
typ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘
357 computation.lift_rel (lift_rel_o R (lift_rel R)) (destruct s) (destruct t)
id └──────────────────┘ └────────┘ ┴ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
src └──────────────────┘ └────────┘ └──────┘ └──────┘ └──────┘
typ └──────────────────┘ └────────┘ ┴ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc └──────────────────┘ └──────┘ └──────┘ └──────┘
358 | ⟨R, h1, h2⟩ :=
359 by refine computation.lift_rel.imp _ _ _ (h2 h1);
id └──────────────────────┘ └┘ └┘
src └─────┘└──────────────────────┘└─────┘ ┴ ┴
typ └─────┘└──────────────────────┘└─────┘ └┘┴└┘┴
doc └─────┘ └─────┘ ┴ ┴
txt └─────┘ └─────┘ ┴ ┴
par └─────┘ └─────┘ ┴ ┴
pid ┴ └─────┘ ┴ ┴
st └───────────────────────────────────────────────
360 apply lift_rel_o.imp_right; exact λ s' t' h', ⟨R, h', @h2⟩
id └──────────────────┘ ┴ └┘
src └────┘└──────────────────┘ └────┘ └─────────┘ └┘ └┘ └─
typ └────┘└──────────────────┘ └────┘ └─────────┘ ┴└┘ └┘ └┘└─
doc └────┘ └────┘ └─────────┘ └┘ └┘ └─
txt └────┘ └────┘ └─────────┘ └┘ └┘ └─
par └────┘ └────┘ └─────────┘ └┘ └┘ └─
pid ┴ ┴ └─────────┘ └┘ └┘ ┴└
st ────────────────────────────────────────────────────────────────
361
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
362 theorem lift_rel_destruct_iff {R : α → β → Prop} {s : wseq α} {t : wseq β} :
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
363 lift_rel R s t ↔
id └──────┘ ┴ ┴ ┴ ┴
src └──────┘ ┴
typ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘
364 computation.lift_rel (lift_rel_o R (lift_rel R)) (destruct s) (destruct t) :=
id └──────────────────┘ └────────┘ ┴ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
src └──────────────────┘ └────────┘ └──────┘ └──────┘ └──────┘
typ └──────────────────┘ └────────┘ ┴ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc └──────────────────┘ └──────┘ └──────┘ └──────┘
365 ⟨lift_rel_destruct, λ h, ⟨λ s t, lift_rel R s t ∨
id └───────────────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴
src └───────────────┘ └──────┘ ┴
typ └───────────────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴
doc └──────┘
366 computation.lift_rel (lift_rel_o R (lift_rel R)) (destruct s) (destruct t),
id └──────────────────┘ └────────┘ ┴ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
src └──────────────────┘ └────────┘ └──────┘ └──────┘ └──────┘
typ └──────────────────┘ └────────┘ ┴ └──────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc └──────────────────┘ └──────┘ └──────┘ └──────┘
367 or.inr h, λ s t h, begin
id └────┘ ┴ ┴ ┴ ┴
src └────┘
typ └────┘ ┴ ┴ ┴ ┴
st └─────
368 have h : computation.lift_rel (lift_rel_o R (lift_rel R)) (destruct s) (destruct t),
id └──────────────────┘ └────────┘ └──────┘ ┴ ┴ └──────┘ ┴
src └───────┘└──────────────────┘┴ └────────┘┴ ┴ └──────┘┴ └─┘ ┴ └┘ └──────┘┴ ┴
typ └───────┘└──────────────────┘┴ └────────┘┴ ┴ └──────┘┴┴└─┘ ┴┴└┘ └──────┘┴┴┴
doc └───────┘└──────────────────┘┴ ┴ ┴ └──────┘┴ └─┘ ┴ └┘ └──────┘┴ ┴
txt └───────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴ ┴
par └───────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴ ┴
pid └────┘└─┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴ ┴
st ──────────────────────────────────────────────────────────────────────────────────────┘└─
369 { cases h with h h, exact lift_rel_destruct h, assumption },
id ┴ └───────────────┘ ┴
src └────┘ └───────┘ └────┘└───────────────┘┴ └─────────┘
typ └────┘┴└───────┘ └────┘└───────────────┘┴┴ └─────────┘
doc └────┘ └───────┘ └────┘ ┴ └─────────┘
txt └────┘ └───────┘ └────┘ ┴ └─────────┘
par └────┘ └───────┘ └────┘ ┴ └─────────┘
pid ┴ └───────┘ ┴ ┴ ┴
st ─────┘└──────────────┘└─────────────────────────┘└───────────┘└┘└
370 apply computation.lift_rel.imp _ _ _ h,
id └──────────────────────┘ ┴
src └────┘└──────────────────────┘└─────┘
typ └────┘└──────────────────────┘└─────┘┴
doc └────┘ └─────┘
txt └────┘ └─────┘
par └────┘ └─────┘
pid ┴ └─────┘
st ─────────────────────────────────────────┘└─
371 intros a b, apply lift_rel_o.imp_right,
id └──────────────────┘
src └────────┘ └────┘└──────────────────┘
typ └────────┘ └────┘└──────────────────┘
doc └────────┘ └────┘
txt └────────┘ └────┘
par └────────┘ └────┘
pid └──┘ ┴
st ─────────────┘└──────────────────────────┘└─
372 intros s t, apply or.inl
id └────┘
src └────────┘ └────┘└────┘└
typ └────────┘ └────┘└────┘└
doc └────────┘ └────┘ └
txt └────────┘ └────┘ └
par └────────┘ └────┘ └
pid └──┘ ┴ └
st ─────────────┘└──────────────
373 end⟩⟩
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
374
375 infix ~ := equiv
id └───┘
src └───┘
typ └───┘
doc └───┘
376
377 theorem destruct_congr {s t : wseq α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
378 s ~ t → computation.lift_rel (bisim_o (~)) (destruct s) (destruct t) :=
id ┴ ┴ ┴ └──────────────────┘ └─────┘ ┴ └──────┘ ┴ └──────┘ ┴
src ┴ └──────────────────┘ └─────┘ ┴ └──────┘ └──────┘
typ ┴ ┴ ┴ └──────────────────┘ └─────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc ┴ └──────────────────┘ ┴ └──────┘ └──────┘
379 lift_rel_destruct
id └───────────────┘
src └───────────────┘
typ └───────────────┘
380
381 theorem destruct_congr_iff {s t : wseq α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
382 s ~ t ↔ computation.lift_rel (bisim_o (~)) (destruct s) (destruct t) :=
id ┴ ┴ ┴ ┴ └──────────────────┘ └─────┘ ┴ └──────┘ ┴ └──────┘ ┴
src ┴ ┴ └──────────────────┘ └─────┘ ┴ └──────┘ └──────┘
typ ┴ ┴ ┴ ┴ └──────────────────┘ └─────┘ ┴ └──────┘ ┴ └──────┘ ┴
doc ┴ └──────────────────┘ ┴ └──────┘ └──────┘
383 lift_rel_destruct_iff
id └───────────────────┘
src └───────────────────┘
typ └───────────────────┘
384
385 theorem lift_rel.refl (R : α → α → Prop) (H : reflexive R) : reflexive (lift_rel R) :=
id ┴ ┴ └───────┘ ┴ └───────┘ └──────┘ ┴
src └───────┘ └───────┘ └──────┘
typ ┴ ┴ └───────┘ ┴ └───────┘ └──────┘ ┴
doc └──────┘
386 λ s, begin
id ┴
typ ┴
st └─────
387 refine ⟨(=), rfl, λ s t (h : s = t), _⟩,
id ┴ └─┘ ┴
src └─────┘ ┴└──┘└─┘└┘ └────────┘ ┴ ┴ └───┘
typ └─────┘ ┴└──┘└─┘└┘ └────────┘ ┴┴┴ └───┘
doc └─────┘ └──┘ └┘ └────────┘ ┴ ┴ └───┘
txt └─────┘ └──┘ └┘ └────────┘ ┴ ┴ └───┘
par └─────┘ └──┘ └┘ └────────┘ ┴ ┴ └───┘
pid ┴ └──┘ └┘ └────────┘ ┴ ┴ └───┘
st ────────────────────────────────────────┘└─
388 rw ←h, apply computation.lift_rel.refl,
id ┴ └───────────────────────┘
src └──┘ └────┘└───────────────────────┘
typ └──┘┴ └────┘└───────────────────────┘
doc └──┘ └────┘
txt └──┘ └────┘
par └──┘ └────┘
pid └┘ ┴
st ──────┘└───────────────────────────────┘└─
389 intro a, cases a with a, simp, cases a; simp, apply H
id ┴ ┴
src └─────┘ └────┘ └─────┘ └──┘ └────┘ └──┘ └────┘ ┴
typ └─────┘ └────┘┴└─────┘ └──┘ └────┘┴ └──┘ └────┘ ┴
doc └─────┘ └────┘ └─────┘ └──┘ └────┘ └──┘ └────┘ ┴
txt └─────┘ └────┘ └─────┘ └──┘ └────┘ └──┘ └────┘ ┴
par └─────┘ └────┘ └─────┘ └──┘ └────┘ └──┘ └────┘ ┴
pid └┘ ┴ └─────┘ ┴ ┴ ┴
st ────────┘└──────────────┘└────┘└─────────────┘└────────┘
390 end
st └─┘
391
392 theorem lift_rel_o.swap (R : α → β → Prop) (C) :
id ┴ ┴
typ ┴ ┴
393 function.swap (lift_rel_o R C) = lift_rel_o (function.swap R) (function.swap C) :=
id └───────────┘ └────────┘ ┴ ┴ ┴ └────────┘ └───────────┘ ┴ └───────────┘ ┴
src └───────────┘ └────────┘ ┴ └────────┘ └───────────┘ └───────────┘
typ └───────────┘ └────────┘ ┴ ┴ ┴ └────────┘ └───────────┘ ┴ └───────────┘ ┴
394 by funext x y; cases x with x; [skip, cases x]; { cases y with y; [skip, cases y]; refl }
id ┴ ┴ ┴ ┴ ┴ ┴
src └────────┘ └────┘ └─────┘ ┴└──┘ └────┘ └────┘ └─────┘ ┴└──┘ └────┘ └───┘
typ └────────┘ └────┘┴└─────┘ ┴└──┘ └────┘┴ └────┘┴└─────┘ ┴└──┘ └────┘┴ └───┘
doc └────────┘ └────┘ └─────┘ └──┘ └────┘ └────┘ └─────┘ └──┘ └────┘ └───┘
txt └────────┘ └────┘ └─────┘ └──┘ └────┘ └────┘ └─────┘ └──┘ └────┘ └───┘
par └────────┘ └────┘ └─────┘ └──┘ └────┘ └────┘ └─────┘ └──┘ └────┘ └───┘
pid └──┘ ┴ └─────┘ ┴ ┴ └─────┘ ┴ ┴
st └────────────────────────────────────────────┘└──────────────────────────────────────┘└┘
395
396 theorem lift_rel.swap_lem {R : α → β → Prop} {s1 s2} (h : lift_rel R s1 s2) :
id ┴ ┴ └──────┘ ┴ └┘ └┘
src └──────┘
typ ┴ ┴ └──────┘ ┴ └┘ └┘
doc └──────┘
397 lift_rel (function.swap R) s2 s1 :=
id └──────┘ └───────────┘ ┴ └┘ └┘
src └──────┘ └───────────┘
typ └──────┘ └───────────┘ ┴ └┘ └┘
doc └──────┘
398 begin
st └─────
399 refine ⟨function.swap (lift_rel R), h, λ s t (h : lift_rel R t s), _⟩,
id └───────────┘ ┴ └──────┘ ┴
src └─────┘ └───────────┘┴ ┴ └─┘ └┘ └────────┘└──────┘┴ ┴ ┴ └───┘
typ └─────┘ └───────────┘┴ ┴ └─┘┴└┘ └────────┘└──────┘┴┴┴ ┴ └───┘
doc └─────┘ ┴ ┴ └─┘ └┘ └────────┘└──────┘┴ ┴ ┴ └───┘
txt └─────┘ ┴ ┴ └─┘ └┘ └────────┘ ┴ ┴ ┴ └───┘
par └─────┘ ┴ ┴ └─┘ └┘ └────────┘ ┴ ┴ ┴ └───┘
pid ┴ ┴ ┴ └─┘ └┘ └────────┘ ┴ ┴ ┴ └───┘
st ──────────────────────────────────────────────────────────────────────┘└─
400 rw [←lift_rel_o.swap, computation.lift_rel.swap],
id └─────────────┘ └───────────────────────┘
src └───┘└─────────────┘└┘└───────────────────────┘┴
typ └───┘└─────────────┘└┘└───────────────────────┘┴
doc └───┘ └┘ ┴
txt └───┘ └┘ ┴
par └───┘ └┘ ┴
pid └─┘ └┘ ┴
st ─────────────────────┘└─────────────────────────┘└──
401 apply lift_rel_destruct h
id └───────────────┘ ┴
src └────┘└───────────────┘┴ ┴
typ └────┘└───────────────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───────────────────────────┘
402 end
st └─┘
403
404 theorem lift_rel.swap (R : α → β → Prop) :
id ┴ ┴
typ ┴ ┴
405 function.swap (lift_rel R) = lift_rel (function.swap R) :=
id └───────────┘ └──────┘ ┴ ┴ └──────┘ └───────────┘ ┴
src └───────────┘ └──────┘ ┴ └──────┘ └───────────┘
typ └───────────┘ └──────┘ ┴ ┴ └──────┘ └───────────┘ ┴
doc └──────┘ └──────┘
406 funext $ λ x, funext $ λ y, propext ⟨lift_rel.swap_lem, lift_rel.swap_lem⟩
id └────┘ ┴ └────┘ ┴ └─────┘ └───────────────┘ └───────────────┘
src └────┘ └────┘ └─────┘ └───────────────┘ └───────────────┘
typ └────┘ ┴ └────┘ ┴ └─────┘ └───────────────┘ └───────────────┘
407
408 theorem lift_rel.symm (R : α → α → Prop) (H : symmetric R) : symmetric (lift_rel R) :=
id ┴ ┴ └───────┘ ┴ └───────┘ └──────┘ ┴
src └───────┘ └───────┘ └──────┘
typ ┴ ┴ └───────┘ ┴ └───────┘ └──────┘ ┴
doc └──────┘
409 λ s1 s2 (h : function.swap (lift_rel R) s2 s1),
id └┘ └┘ └───────────┘ └──────┘ ┴ └┘ └┘
src └───────────┘ └──────┘
typ └┘ └┘ └───────────┘ └──────┘ ┴ └┘ └┘
doc └──────┘
410 by rwa [lift_rel.swap, show function.swap R = R, from
id └───────────┘ └───────────┘ ┴ ┴
src └───┘└───────────┘└┘ ┴└───────────┘┴ ┴┴┴ └──────
typ └───┘└───────────┘└┘ ┴└───────────┘┴ ┴┴┴┴└──────
doc └───┘ └┘ ┴ ┴ ┴ ┴ └──────
txt └───┘ └┘ ┴ ┴ ┴ ┴ └──────
par └───┘ └┘ ┴ ┴ ┴ ┴ └──────
pid └┘ └┘ ┴ ┴ ┴ ┴ └──────
st └─────────────────┘└────────────────────────────────
411 funext $ λ a, funext $ λ b, propext $ by constructor; apply H] at h
id └────┘ └─────┘
src ───────┘ ┴ ┴ └──┘└────┘┴ ┴ └──┘└─────┘┴ ┴ ┴└─────────┘└┘└────┘ └──────
typ ───────┘ ┴ ┴ └──┘└────┘┴ ┴ └──┘└─────┘┴ ┴ ┴└─────────┘└┘└────┘ └──────
doc ───────┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴└─────────┘└┘└────┘ └──────
txt ───────┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴└─────────┘└┘└────┘ └──────
par ───────┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴└─────────┘└┘└────┘ └──────
pid ───────┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ └──────────────────┘ ┴└───┘└
st ───────────────────────────────────────────────┘└───────────────────┘┴└─────
412
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
413 theorem lift_rel.trans (R : α → α → Prop) (H : transitive R) : transitive (lift_rel R) :=
id ┴ ┴ └────────┘ ┴ └────────┘ └──────┘ ┴
src └────────┘ └────────┘ └──────┘
typ ┴ ┴ └────────┘ ┴ └────────┘ └──────┘ ┴
doc └──────┘
414 λ s t u h1 h2, begin
id ┴ ┴ ┴ └┘ └┘
typ ┴ ┴ ┴ └┘ └┘
st └─────
415 refine ⟨λ s u, ∃ t, lift_rel R s t ∧ lift_rel R t u, ⟨t, h1, h2⟩, λ s u h, _⟩,
id ┴ ┴ ┴ └──────┘ ┴ ┴ └┘ └┘
src └─────┘ └────┘┴└┘┴┴ ┴ ┴ ┴ ┴┴┴└──────┘┴ ┴ ┴ └┘ └┘ └┘ └─┘ └────────┘
typ └─────┘ └────┘┴└┘┴┴ ┴ ┴ ┴ ┴┴┴└──────┘┴┴┴ ┴ └┘ ┴└┘└┘└┘└┘└─┘ └────────┘
doc └─────┘ └────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴└──────┘┴ ┴ ┴ └┘ └┘ └┘ └─┘ └────────┘
txt └─────┘ └────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └┘ └─┘ └────────┘
par └─────┘ └────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └┘ └─┘ └────────┘
pid ┴ └────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └┘ └─┘ └────────┘
st ──────────────────────────────────────────────────────────────────────────────┘└─
416 rcases h with ⟨t, h1, h2⟩,
id ┴
src └─────┘ └───────────────┘
typ └─────┘┴└───────────────┘
doc └─────┘ └───────────────┘
txt └─────┘ └───────────────┘
par └─────┘ └───────────────┘
pid ┴ └───────────────┘
st ──────────────────────────┘└─
417 have h1 := lift_rel_destruct h1,
id └───────────────┘ └┘
src └─────────┘└───────────────┘┴
typ └─────────┘└───────────────┘┴└┘
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid └─────┘┴└─┘ ┴
st ────────────────────────────────┘└─
418 have h2 := lift_rel_destruct h2,
id └───────────────┘ └┘
src └─────────┘└───────────────┘┴
typ └─────────┘└───────────────┘┴└┘
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid └─────┘┴└─┘ ┴
st ────────────────────────────────┘└─
419 refine computation.lift_rel_def.2
id └──────────────────────┘
src └─────┘└──────────────────────┘└──
typ └─────┘└──────────────────────┘└──
doc └─────┘ └──
txt └─────┘ └──
par └─────┘ └──
pid ┴ └──
st ────────────────────────────────────
420 ⟨(computation.terminates_of_lift_rel h1).trans
id └┘
src ───┘ ┴ └───────
typ ───┘ ┴└┘└───────
doc ───┘ ┴ └───────
txt ───┘ ┴ └───────
par ───┘ ┴ └───────
pid ───┘ ┴ └───────
st ───────────────────────────────────────────────────
421 (computation.terminates_of_lift_rel h2), λ a c ha hc, _⟩,
id └────────────────────────────────┘ └┘
src ────┘ └────────────────────────────────┘┴ └─┘ └────────────┘
typ ────┘ └────────────────────────────────┘┴└┘└─┘ └────────────┘
doc ────┘ ┴ └─┘ └────────────┘
txt ────┘ ┴ └─┘ └────────────┘
par ────┘ ┴ └─┘ └────────────┘
pid ────┘ ┴ └─┘ └────────────┘
st ────────────────────────────────────────────────────────────┘└─
422 rcases h1.left ha with ⟨b, hb, t1⟩,
id └─────┘ └┘
src └─────┘└─────┘┴ └───────────────┘
typ └─────┘└─────┘┴└┘└───────────────┘
doc └─────┘ ┴ └───────────────┘
txt └─────┘ ┴ └───────────────┘
par └─────┘ ┴ └───────────────┘
pid ┴ ┴ └───────────────┘
st ───────────────────────────────────┘└─
423 have t2 := computation.rel_of_lift_rel h2 hb hc,
id └─────────────────────────┘ └┘ └┘ └┘
src └─────────┘└─────────────────────────┘┴ ┴ ┴
typ └─────────┘└─────────────────────────┘┴└┘┴└┘┴└┘
doc └─────────┘ ┴ ┴ ┴
txt └─────────┘ ┴ ┴ ┴
par └─────────┘ ┴ ┴ ┴
pid └─────┘┴└─┘ ┴ ┴ ┴
st ────────────────────────────────────────────────┘└─
424 cases a with a; cases c with c,
id ┴ ┴
src └────┘ └─────┘ └────┘ └─────┘
typ └────┘┴└─────┘ └────┘┴└─────┘
doc └────┘ └─────┘ └────┘ └─────┘
txt └────┘ └─────┘ └────┘ └─────┘
par └────┘ └─────┘ └────┘ └─────┘
pid ┴ └─────┘ ┴ └─────┘
st ───────────────────────────────┘└─
425 { trivial },
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid ┴
st ───┘└──────┘└┘└
426 { cases b, {cases t2}, {cases t1} },
id ┴ └┘ └┘
src └────┘ └────┘ └────┘
typ └────┘┴ └────┘└┘ └────┘└┘
doc └────┘ └────┘ └────┘
txt └────┘ └────┘ └────┘
par └────┘ └────┘ └────┘
pid ┴ ┴ ┴
st ───┘└─────┘└─────────┘└┘└────────┘└──┘└
427 { cases a, cases b with b, {cases t1}, {cases b, cases t2} },
id ┴ ┴ └┘ ┴ └┘
src └────┘ └────┘ └─────┘ └────┘ └────┘ └────┘
typ └────┘┴ └────┘┴└─────┘ └────┘└┘ └────┘┴ └────┘└┘
doc └────┘ └────┘ └─────┘ └────┘ └────┘ └────┘
txt └────┘ └────┘ └─────┘ └────┘ └────┘ └────┘
par └────┘ └────┘ └─────┘ └────┘ └────┘ └────┘
pid ┴ ┴ └─────┘ ┴ ┴ ┴
st ───┘└─────┘└──────────────┘└─────────┘└┘└───────┘└────────┘└──┘└
428 { cases a with a s, cases b with b, {cases t1},
id ┴ ┴ └┘
src └────┘ └───────┘ └────┘ └─────┘ └────┘
typ └────┘┴└───────┘ └────┘┴└─────┘ └────┘└┘
doc └────┘ └───────┘ └────┘ └─────┘ └────┘
txt └────┘ └───────┘ └────┘ └─────┘ └────┘
par └────┘ └───────┘ └────┘ └─────┘ └────┘
pid ┴ └───────┘ ┴ └─────┘ ┴
st ───────────────────┘└──────────────┘└─────────┘└┘└
429 cases b with b t, cases c with c u,
id ┴ ┴
src └────┘ └───────┘ └────┘ └───────┘
typ └────┘┴└───────┘ └────┘┴└───────┘
doc └────┘ └───────┘ └────┘ └───────┘
txt └────┘ └───────┘ └────┘ └───────┘
par └────┘ └───────┘ └────┘ └───────┘
pid ┴ └───────┘ ┴ └───────┘
st ───────────────────┘└────────────────┘└─
430 cases t1 with ab st, cases t2 with bc tu,
id └┘ └┘
src └────┘ └─────────┘ └────┘ └─────────┘
typ └────┘└┘└─────────┘ └────┘└┘└─────────┘
doc └────┘ └─────────┘ └────┘ └─────────┘
txt └────┘ └─────────┘ └────┘ └─────────┘
par └────┘ └─────────┘ └────┘ └─────────┘
pid ┴ └─────────┘ ┴ └─────────┘
st ──────────────────────┘└───────────────────┘└─
431 exact ⟨H ab bc, t, st, tu⟩ }
id ┴ └┘ └┘ ┴ └┘ └┘
src └────┘ ┴ ┴ └┘ └┘ └┘ └┘
typ └────┘ ┴┴└┘┴└┘└┘┴└┘└┘└┘└┘└┘
doc └────┘ ┴ ┴ └┘ └┘ └┘ └┘
txt └────┘ ┴ ┴ └┘ └┘ └┘ └┘
par └────┘ ┴ ┴ └┘ └┘ └┘ └┘
pid ┴ ┴ ┴ └┘ └┘ └┘ ┴┴
st ──────────────────────────────┘└─
432 end
st ──┘
433
434 theorem lift_rel.equiv (R : α → α → Prop) : equivalence R → equivalence (lift_rel R)
id ┴ ┴ └─────────┘ ┴ ┴ └─────────┘ └──────┘ ┴
src └─────────┘ └─────────┘ └──────┘
typ ┴ ┴ └─────────┘ ┴ ┴ └─────────┘ └──────┘ ┴
doc └──────┘
435 | ⟨refl, symm, trans⟩ :=
id └──┘ └──┘ └───┘
src └──┘ └──┘ └───┘
typ └──┘ └──┘ └───┘
436 ⟨lift_rel.refl R refl, lift_rel.symm R symm, lift_rel.trans R trans⟩
id └───────────┘ ┴ └───────────┘ ┴ └────────────┘ ┴
src └───────────┘ └───────────┘ └────────────┘
typ └───────────┘ ┴ └───────────┘ ┴ └────────────┘ ┴
437
438 @[refl] theorem equiv.refl : ∀ (s : wseq α), s ~ s :=
id └──┘ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴
doc └──┘ └──┘ ┴
439 lift_rel.refl (=) eq.refl
id └───────────┘ ┴ └─────┘
src └───────────┘ ┴ └─────┘
typ └───────────┘ ┴ └─────┘
440
441 @[symm] theorem equiv.symm : ∀ {s t : wseq α}, s ~ t → t ~ s :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘ ┴ ┴
442 lift_rel.symm (=) (@eq.symm _)
id └───────────┘ ┴ └─────┘
src └───────────┘ ┴ └─────┘
typ └───────────┘ ┴ └─────┘
443
444 @[trans] theorem equiv.trans : ∀ {s t u : wseq α}, s ~ t → t ~ u → s ~ u :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └───┘ └──┘ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └───┘ └──┘ ┴ ┴ ┴
445 lift_rel.trans (=) (@eq.trans _)
id └────────────┘ ┴ └──────┘
src └────────────┘ ┴ └──────┘
typ └────────────┘ ┴ └──────┘
446
447 theorem equiv.equivalence : equivalence (@equiv α) :=
id └─────────┘ └───┘ ┴
src └─────────┘ └───┘
typ └─────────┘ └───┘ ┴
doc └───┘
448 ⟨@equiv.refl _, @equiv.symm _, @equiv.trans _⟩
id └────────┘ └────────┘ └─────────┘
src └────────┘ └────────┘ └─────────┘
typ └────────┘ └────────┘ └─────────┘
449
450 open computation
451 local notation `return` := computation.return
id └────────────────┘
src └────────────────┘
typ └────────────────┘
doc └────────────────┘
452
453 @[simp] theorem destruct_nil : destruct (nil : wseq α) = return none :=
id └──────┘ └─┘ └──┘ ┴ ┴ └────┘ └──┘
src └──────┘ └─┘ └──┘ ┴ └────┘ └──┘
typ └──────┘ └─┘ └──┘ ┴ ┴ └────┘ └──┘
doc └──┘ └──────┘ └─┘ └──┘ └────┘
454 computation.destruct_eq_ret rfl
id └─────────────────────────┘ └─┘
src └─────────────────────────┘ └─┘
typ └─────────────────────────┘ └─┘
455
456 @[simp] theorem destruct_cons (a : α) (s) : destruct (cons a s) = return (some (a, s)) :=
id ┴ └──────┘ └──┘ ┴ ┴ ┴ └────┘ └──┘ ┴┴ ┴
src └──────┘ └──┘ ┴ └────┘ └──┘ ┴
typ ┴ └──────┘ └──┘ ┴ ┴ ┴ └────┘ └──┘ ┴┴ ┴
doc └──┘ └──────┘ └──┘ └────┘
457 computation.destruct_eq_ret $ by simp [destruct, cons, computation.rmap]
id └─────────────────────────┘ └──────┘ └──┘ └──────────────┘
src └─────────────────────────┘ └────┘└──────┘└┘└──┘└┘└──────────────┘└─
typ └─────────────────────────┘ └────┘└──────┘└┘└──┘└┘└──────────────┘└─
doc └────┘└──────┘└┘└──┘└┘└──────────────┘└─
txt └────┘ └┘ └┘ └─
par └────┘ └┘ └┘ └─
pid ┴┴ └┘ └┘ ┴└
st └────────────────────────────────────────
458
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
459 @[simp] theorem destruct_think (s : wseq α) : destruct (think s) = (destruct s).think :=
id └──┘ ┴ └──────┘ └───┘ ┴ ┴ └──────┘ ┴ └───┘
src └──┘ └──────┘ └───┘ ┴ └──────┘ └───┘
typ └──┘ ┴ └──────┘ └───┘ ┴ ┴ └──────┘ ┴ └───┘
doc └──┘ └──┘ └──────┘ └───┘ └──────┘ └───┘
460 computation.destruct_eq_think $ by simp [destruct, think, computation.rmap]
id └───────────────────────────┘ └──────┘ └───┘ └──────────────┘
src └───────────────────────────┘ └────┘└──────┘└┘└───┘└┘└──────────────┘└─
typ └───────────────────────────┘ └────┘└──────┘└┘└───┘└┘└──────────────┘└─
doc └────┘└──────┘└┘└───┘└┘└──────────────┘└─
txt └────┘ └┘ └┘ └─
par └────┘ └┘ └┘ └─
pid ┴┴ └┘ └┘ ┴└
st └─────────────────────────────────────────
461
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
462 @[simp] theorem seq_destruct_nil : seq.destruct (nil : wseq α) = none :=
id └──────────┘ └─┘ └──┘ ┴ ┴ └──┘
src └──────────┘ └─┘ └──┘ ┴ └──┘
typ └──────────┘ └─┘ └──┘ ┴ ┴ └──┘
doc └──┘ └──────────┘ └─┘ └──┘
463 seq.destruct_nil
id └──────────────┘
src └──────────────┘
typ └──────────────┘
464
465 @[simp] theorem seq_destruct_cons (a : α) (s) : seq.destruct (cons a s) = some (some a, s) :=
id ┴ └──────────┘ └──┘ ┴ ┴ ┴ └──┘ ┴└──┘ ┴ ┴
src └──────────┘ └──┘ ┴ └──┘ ┴└──┘
typ ┴ └──────────┘ └──┘ ┴ ┴ ┴ └──┘ ┴└──┘ ┴ ┴
doc └──┘ └──────────┘ └──┘
466 seq.destruct_cons _ _
id └───────────────┘
src └───────────────┘
typ └───────────────┘
467
468 @[simp] theorem seq_destruct_think (s : wseq α) : seq.destruct (think s) = some (none, s) :=
id └──┘ ┴ └──────────┘ └───┘ ┴ ┴ └──┘ ┴└──┘ ┴
src └──┘ └──────────┘ └───┘ ┴ └──┘ ┴└──┘
typ └──┘ ┴ └──────────┘ └───┘ ┴ ┴ └──┘ ┴└──┘ ┴
doc └──┘ └──┘ └──────────┘ └───┘
469 seq.destruct_cons _ _
id └───────────────┘
src └───────────────┘
typ └───────────────┘
470
471 @[simp] theorem head_nil : head (nil : wseq α) = return none := by simp [head]; refl
id └──┘ └─┘ └──┘ ┴ ┴ └────┘ └──┘ └──┘
src └──┘ └─┘ └──┘ ┴ └────┘ └──┘ └────┘└──┘┴ └───┘
typ └──┘ └─┘ └──┘ ┴ ┴ └────┘ └──┘ └────┘└──┘┴ └───┘
doc └──┘ └──┘ └─┘ └──┘ └────┘ └────┘└──┘┴ └───┘
txt └────┘ ┴ └───┘
par └────┘ ┴ └───┘
pid ┴┴ ┴ ┴
st └─────────────────┘
472 @[simp] theorem head_cons (a : α) (s) : head (cons a s) = return (some a) := by simp [head]; refl
id ┴ └──┘ └──┘ ┴ ┴ ┴ └────┘ └──┘ ┴ └──┘
src └──┘ └──┘ ┴ └────┘ └──┘ └────┘└──┘┴ └───┘
typ ┴ └──┘ └──┘ ┴ ┴ ┴ └────┘ └──┘ ┴ └────┘└──┘┴ └───┘
doc └──┘ └──┘ └──┘ └────┘ └────┘└──┘┴ └───┘
txt └────┘ ┴ └───┘
par └────┘ ┴ └───┘
pid ┴┴ ┴ ┴
st └─────────────────┘
473 @[simp] theorem head_think (s : wseq α) : head (think s) = (head s).think := by simp [head]; refl
id └──┘ ┴ └──┘ └───┘ ┴ ┴ └──┘ ┴ └───┘ └──┘
src └──┘ └──┘ └───┘ ┴ └──┘ └───┘ └────┘└──┘┴ └────
typ └──┘ ┴ └──┘ └───┘ ┴ ┴ └──┘ ┴ └───┘ └────┘└──┘┴ └────
doc └──┘ └──┘ └──┘ └───┘ └──┘ └───┘ └────┘└──┘┴ └────
txt └────┘ ┴ └────
par └────┘ ┴ └────
pid ┴┴ ┴ └
st └──────────────────
474
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
475 @[simp] theorem flatten_ret (s : wseq α) : flatten (return s) = s :=
id └──┘ ┴ └─────┘ └────┘ ┴ ┴ ┴
src └──┘ └─────┘ └────┘ ┴
typ └──┘ ┴ └─────┘ └────┘ ┴ ┴ ┴
doc └──┘ └──┘ └─────┘ └────┘
476 begin
st └─────
477 refine seq.eq_of_bisim (λs1 s2, flatten (return s2) = s1) _ rfl,
id └─────────────┘ └─────┘ └────┘ ┴ └─┘
src └─────┘└─────────────┘┴ └─────┘└─────┘┴ └────┘┴ └┘┴┴ └──┘└─┘
typ └─────┘└─────────────┘┴ └─────┘└─────┘┴ └────┘┴ └┘┴┴ └──┘└─┘
doc └─────┘ ┴ └─────┘└─────┘┴ └────┘┴ └┘ ┴ └──┘
txt └─────┘ ┴ └─────┘ ┴ ┴ └┘ ┴ └──┘
par └─────┘ ┴ └─────┘ ┴ ┴ └┘ ┴ └──┘
pid ┴ ┴ └─────┘ ┴ ┴ └┘ ┴ └──┘
st ────────────────────────────────────────────────────────────────┘└─
478 intros s' s h, rw ←h, simp [flatten],
id ┴ └─────┘
src └───────────┘ └──┘ └────┘└─────┘┴
typ └───────────┘ └──┘┴ └────┘└─────┘┴
doc └───────────┘ └──┘ └────┘└─────┘┴
txt └───────────┘ └──┘ └────┘ ┴
par └───────────┘ └──┘ └────┘ ┴
pid └─────┘ └┘ ┴┴ ┴
st ──────────────┘└─────┘└──────────────┘└─
479 cases seq.destruct s, { simp },
id └──────────┘ ┴
src └────┘└──────────┘┴ └───┘
typ └────┘└──────────┘┴┴ └───┘
doc └────┘└──────────┘┴ └───┘
txt └────┘ ┴ └───┘
par └────┘ ┴ └───┘
pid ┴ ┴ ┴
st ─────────────────────┘└──┘└───┘└┘└
480 { cases val with o s', simp }
id └─┘
src └────┘ └────────┘ └───┘
typ └────┘└─┘└────────┘ └───┘
doc └────┘ └────────┘ └───┘
txt └────┘ └────────┘ └───┘
par └────┘ └────────┘ └───┘
pid ┴ └────────┘ ┴
st ──────────────────────┘└─────┘└─
481 end
st ──┘
482
483 @[simp] theorem flatten_think (c : computation (wseq α)) : flatten c.think = think (flatten c) :=
id └─────────┘ └──┘ ┴ └─────┘ ┴└────┘ ┴ └───┘ └─────┘ ┴
src └─────────┘ └──┘ └─────┘ └────┘ ┴ └───┘ └─────┘
typ └─────────┘ └──┘ ┴ └─────┘ ┴└────┘ ┴ └───┘ └─────┘ ┴
doc └──┘ └─────────┘ └──┘ └─────┘ └────┘ └───┘ └─────┘
484 seq.destruct_eq_cons $ by simp [flatten, think]
id └──────────────────┘ └─────┘ └───┘
src └──────────────────┘ └────┘└─────┘└┘└───┘└─
typ └──────────────────┘ └────┘└─────┘└┘└───┘└─
doc └────┘└─────┘└┘└───┘└─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └──────────────────────
485
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
486 @[simp] theorem destruct_flatten (c : computation (wseq α)) : destruct (flatten c) = c >>= destruct :=
id └─────────┘ └──┘ ┴ └──────┘ └─────┘ ┴ ┴ ┴ └─┘ └──────┘
src └─────────┘ └──┘ └──────┘ └─────┘ ┴ └─┘ └──────┘
typ └─────────┘ └──┘ ┴ └──────┘ └─────┘ ┴ ┴ ┴ └─┘ └──────┘
doc └──┘ └─────────┘ └──┘ └──────┘ └─────┘ └──────┘
487 begin
st └─────
488 refine computation.eq_of_bisim (λc1 c2, c1 = c2 ∨
id └─────────────────────┘ ┴ ┴
src └─────┘└─────────────────────┘┴ └─────┘ ┴┴┴ ┴┴└
typ └─────┘└─────────────────────┘┴ └─────┘ ┴┴┴ ┴┴└
doc └─────┘ ┴ └─────┘ ┴ ┴ ┴ └
txt └─────┘ ┴ └─────┘ ┴ ┴ ┴ └
par └─────┘ ┴ └─────┘ ┴ ┴ ┴ └
pid ┴ ┴ └─────┘ ┴ ┴ ┴ └
st ────────────────────────────────────────────────────
489 ∃ c, c1 = destruct (flatten c) ∧ c2 = computation.bind c destruct) _ (or.inr ⟨c, rfl, rfl⟩),
id ┴ ┴ └─────┘ ┴ └──────────────┘ └──────┘ └────┘ ┴ └─┘
src ───┘┴└┘┴┴ ┴ ┴ ┴ └─────┘┴ └┘┴┴ ┴ ┴└──────────────┘┴ ┴└──────┘└──┘ └────┘┴ └┘ └┘└─┘└┘
typ ───┘┴└┘┴┴ ┴ ┴ ┴ └─────┘┴ └┘┴┴ ┴ ┴└──────────────┘┴ ┴└──────┘└──┘ └────┘┴ ┴└┘ └┘└─┘└┘
doc ───┘ └┘ ┴ ┴ ┴ ┴ └─────┘┴ └┘ ┴ ┴ ┴└──────────────┘┴ ┴└──────┘└──┘ ┴ └┘ └┘ └┘
txt ───┘ └┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └┘ └┘ └┘
par ───┘ └┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └┘ └┘ └┘
pid ───┘ └┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └┘ └┘ └┘
st ──────────────────────────────────────────────────────────────────────────────────────────────┘└─
490 intros c1 c2 h, exact match c1, c2, h with
id └┘ └┘ ┴
src └────────────┘ └────┘ ┴ └┘ └┘ └─────
typ └────────────┘ └────┘ ┴└┘└┘└┘└┘┴└─────
doc └────────────┘ └────┘ ┴ └┘ └┘ └─────
txt └────────────┘ └────┘ ┴ └┘ └┘ └─────
par └────────────┘ └────┘ ┴ └┘ └┘ └─────
pid └──────┘ ┴ ┴ └┘ └┘ └─────
st ───────────────┘└────────────────────────────
491 | _, _, (or.inl $ eq.refl c) := by cases c.destruct; simp
id └────┘ └─────┘ └────────┘
src ─────────┘ └────┘┴ ┴└─────┘┴ └───┘ ┴└────┘└────────┘└┘└────
typ ─────────┘ └────┘┴ ┴└─────┘┴ └───┘ ┴└────┘└────────┘└┘└────
doc ─────────┘ ┴ ┴ ┴ └───┘ ┴└────┘└────────┘└┘└────
txt ─────────┘ ┴ ┴ ┴ └───┘ ┴└────┘ └┘└────
par ─────────┘ ┴ ┴ ┴ └───┘ ┴└────┘ └┘└────
pid ─────────┘ ┴ ┴ ┴ └───┘ └─────┘ └──────
st ───────────────────────────────────┘└───────────────────────
492 | _, _, (or.inr ⟨c, rfl, rfl⟩) := begin
src ─┘└──────┘ ┴ └┘ └┘ └────┘ └
typ ─┘└──────┘ ┴ └┘ └┘ └────┘ └
doc ─┘└──────┘ ┴ └┘ └┘ └────┘ └
txt ─┘└──────┘ ┴ └┘ └┘ └────┘ └
par ─┘└──────┘ ┴ └┘ └┘ └────┘ └
pid ─────────┘ ┴ └┘ └┘ └────┘ └
st ─┘└────────────────────────────────┘└─────
493 apply c.cases_on (λa, _) (λc', _); repeat {simp},
id └────────┘
src ───┘└────┘└────────┘┴ └────┘ └────┘└┘└──────┘└──┘┴└─
typ ─────────┘└────────┘┴ └────┘ └──────┘└──────┘└──┘┴└─
doc ───┘└────┘ ┴ └────┘ └────┘└┘└──────┘└──┘┴└─
txt ───┘└────┘ ┴ └────┘ └────┘└┘└──────┘└──┘┴└─
par ─────────┘ ┴ └────┘ └──────┘└──────┘└──┘┴└─
pid ─────────┘ ┴ └────┘ └──────────────────────
st ──────────────────────────────────────────────┘└───┘└─
494 { cases (destruct a).destruct; simp },
id └──────┘ ┴
src ─────┘└────┘ └──────┘┴ └────────┘└┘└───┘└──
typ ─────┘└────┘ └──────┘┴┴└────────┘└┘└───┘└──
doc ─────┘└────┘ └──────┘┴ └────────┘└┘└───┘└──
txt ─────┘└────┘ ┴ └────────┘└┘└───┘└──
par ─────┘└────┘ ┴ └────────┘└┘└───┘└──
pid ───────────┘ ┴ └───────────────────
st ────┘└─────────────────────────────────┘┴└─
495 { exact or.inr ⟨c', rfl, rfl⟩ }
id └────┘ └┘ └─┘
src ───────────┘└────┘┴ └┘ └┘└─┘└───
typ ───────────┘└────┘┴ └┘└┘ └┘└─┘└───
doc ───────────┘ ┴ └┘ └┘ └───
txt ───────────┘ ┴ └┘ └┘ └───
par ───────────┘ ┴ └┘ └┘ └───
pid ───────────┘ ┴ └┘ └┘ └───
st ─────────────────────────────────┘└─
496 end end
src ─────────┘
typ ─────────┘
doc ─────────┘
txt ─────────┘
par ─────────┘
pid ────────┘┴
st ────┘└───┘
497 end
st └─┘
498
499 theorem head_terminates_iff (s : wseq α) : terminates (head s) ↔ terminates (destruct s) :=
id └──┘ ┴ └────────┘ └──┘ ┴ ┴ └────────┘ └──────┘ ┴
src └──┘ └────────┘ └──┘ ┴ └────────┘ └──────┘
typ └──┘ ┴ └────────┘ └──┘ ┴ ┴ └────────┘ └──────┘ ┴
doc └──┘ └────────┘ └──┘ └────────┘ └──────┘
500 terminates_map_iff _ (destruct s)
id └────────────────┘ └──────┘ ┴
src └────────────────┘ └──────┘
typ └────────────────┘ └──────┘ ┴
doc └──────┘
501
502 @[simp] theorem tail_nil : tail (nil : wseq α) = nil := by simp [tail]
id └──┘ └─┘ └──┘ ┴ ┴ └─┘ └──┘
src └──┘ └─┘ └──┘ ┴ └─┘ └────┘└──┘└┘
typ └──┘ └─┘ └──┘ ┴ ┴ └─┘ └────┘└──┘└┘
doc └──┘ └──┘ └─┘ └──┘ └─┘ └────┘└──┘└┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st └───────────┘
503 @[simp] theorem tail_cons (a : α) (s) : tail (cons a s) = s := by simp [tail]
id ┴ └──┘ └──┘ ┴ ┴ ┴ ┴ └──┘
src └──┘ └──┘ ┴ └────┘└──┘└┘
typ ┴ └──┘ └──┘ ┴ ┴ ┴ ┴ └────┘└──┘└┘
doc └──┘ └──┘ └──┘ └────┘└──┘└┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st └───────────┘
504 @[simp] theorem tail_think (s : wseq α) : tail (think s) = (tail s).think := by simp [tail]
id └──┘ ┴ └──┘ └───┘ ┴ ┴ └──┘ ┴ └───┘ └──┘
src └──┘ └──┘ └───┘ ┴ └──┘ └───┘ └────┘└──┘└─
typ └──┘ ┴ └──┘ └───┘ ┴ ┴ └──┘ ┴ └───┘ └────┘└──┘└─
doc └──┘ └──┘ └──┘ └───┘ └──┘ └───┘ └────┘└──┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └────────────
505
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
506 @[simp] theorem dropn_nil (n) :
doc └──┘
507 drop (nil : wseq α) n = nil := by induction n; simp [*, drop]
id └──┘ └─┘ └──┘ ┴ ┴ ┴ └─┘ ┴ └──┘
src └──┘ └─┘ └──┘ ┴ └─┘ └────────┘ └───────┘└──┘└┘
typ └──┘ └─┘ └──┘ ┴ ┴ ┴ └─┘ └────────┘┴ └───────┘└──┘└┘
doc └──┘ └─┘ └──┘ └─┘ └────────┘ └───────┘└──┘└┘
txt └────────┘ └───────┘ └┘
par └────────┘ └───────┘ └┘
pid ┴ ┴└──┘ ┴┴
st └───────────────────────────┘
508 @[simp] theorem dropn_cons (a : α) (s) (n) :
id ┴
typ ┴
doc └──┘
509 drop (cons a s) (n+1) = drop s n := by induction n; simp [*, drop]
id └──┘ └──┘ ┴ ┴ ┴┴ ┴ └──┘ ┴ ┴ ┴ └──┘
src └──┘ └──┘ ┴ ┴ └──┘ └────────┘ └───────┘└──┘└┘
typ └──┘ └──┘ ┴ ┴ ┴┴ ┴ └──┘ ┴ ┴ └────────┘┴ └───────┘└──┘└┘
doc └──┘ └──┘ └──┘ └────────┘ └───────┘└──┘└┘
txt └────────┘ └───────┘ └┘
par └────────┘ └───────┘ └┘
pid ┴ ┴└──┘ ┴┴
st └───────────────────────────┘
510 @[simp] theorem dropn_think (s : wseq α) (n) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘ └──┘
511 drop (think s) n = (drop s n).think := by induction n; simp [*, drop]
id └──┘ └───┘ ┴ ┴ ┴ └──┘ ┴ ┴ └───┘ ┴ └──┘
src └──┘ └───┘ ┴ └──┘ └───┘ └────────┘ └───────┘└──┘└─
typ └──┘ └───┘ ┴ ┴ ┴ └──┘ ┴ ┴ └───┘ └────────┘┴ └───────┘└──┘└─
doc └──┘ └───┘ └──┘ └───┘ └────────┘ └───────┘└──┘└─
txt └────────┘ └───────┘ └─
par └────────┘ └───────┘ └─
pid ┴ ┴└──┘ ┴└
st └────────────────────────────
512
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
513 theorem dropn_add (s : wseq α) (m) : ∀ n, drop s (m + n) = drop (drop s m) n
id └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ └──┘ ┴ ┴ ┴
src └──┘ └──┘ ┴ ┴ └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ └──┘ ┴ ┴ ┴
doc └──┘ └──┘ └──┘ └──┘
514 | 0 := rfl
id └─┘
src └─┘
typ └─┘
515 | (n+1) := congr_arg tail (dropn_add n)
id ┴┴ └───────┘ └──┘ └───────┘
src ┴ └───────┘ └──┘
typ ┴┴ └───────┘ └──┘ └───────┘
doc └──┘
516
517 theorem dropn_tail (s : wseq α) (n) : drop (tail s) n = drop s (n + 1) :=
id └──┘ ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴
src └──┘ └──┘ └──┘ ┴ └──┘ ┴
typ └──┘ ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴
doc └──┘ └──┘ └──┘ └──┘
518 by rw add_comm; symmetry; apply dropn_add
id └──────┘ └───────┘
src └─┘└──────┘ └──────┘ └────┘└───────┘└
typ └─┘└──────┘ └──────┘ └────┘└───────┘└
doc └─┘ └──────┘ └────┘ └
txt └─┘ └──────┘ └────┘ └
par └─┘ └──────┘ └────┘ └
pid ┴ ┴ └
st └───────────────────────────────────────
519
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
520 theorem nth_add (s : wseq α) (m n) : nth s (m + n) = nth (drop s m) n :=
id └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─┘ └──┘ ┴ ┴ ┴
src └──┘ └─┘ ┴ ┴ └─┘ └──┘
typ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─┘ └──┘ ┴ ┴ ┴
doc └──┘ └─┘ └─┘ └──┘
521 congr_arg head (dropn_add _ _ _)
id └───────┘ └──┘ └───────┘
src └───────┘ └──┘ └───────┘
typ └───────┘ └──┘ └───────┘
doc └──┘
522
523 theorem nth_tail (s : wseq α) (n) : nth (tail s) n = nth s (n + 1) :=
id └──┘ ┴ └─┘ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴
src └──┘ └─┘ └──┘ ┴ └─┘ ┴
typ └──┘ ┴ └─┘ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴
doc └──┘ └─┘ └──┘ └─┘
524 congr_arg head (dropn_tail _ _)
id └───────┘ └──┘ └────────┘
src └───────┘ └──┘ └────────┘
typ └───────┘ └──┘ └────────┘
doc └──┘
525
526 @[simp] theorem join_nil : join nil = (nil : wseq α) := seq.join_nil
id └──┘ └─┘ ┴ └─┘ └──┘ ┴ └──────────┘
src └──┘ └─┘ ┴ └─┘ └──┘ └──────────┘
typ └──┘ └─┘ ┴ └─┘ └──┘ ┴ └──────────┘
doc └──┘ └──┘ └─┘ └─┘ └──┘
527
528 @[simp] theorem join_think (S : wseq (wseq α)) :
id └──┘ └──┘ ┴
src └──┘ └──┘
typ └──┘ └──┘ ┴
doc └──┘ └──┘ └──┘
529 join (think S) = think (join S) :=
id └──┘ └───┘ ┴ ┴ └───┘ └──┘ ┴
src └──┘ └───┘ ┴ └───┘ └──┘
typ └──┘ └───┘ ┴ ┴ └───┘ └──┘ ┴
doc └──┘ └───┘ └───┘ └──┘
530 by { simp [think, join], unfold functor.map, simp [join, seq1.ret] }
id └───┘ └──┘ └──┘ └──────┘
src └────┘└───┘└┘└──┘┴ └────────────────┘ └────┘└──┘└┘└──────┘└┘
typ └────┘└───┘└┘└──┘┴ └────────────────┘ └────┘└──┘└┘└──────┘└┘
doc └────┘└───┘└┘└──┘┴ └────────────────┘ └────┘└──┘└┘└──────┘└┘
txt └────┘ └┘ ┴ └────────────────┘ └────┘ └┘ └┘
par └────┘ └┘ ┴ └────────────────┘ └────┘ └┘ └┘
pid ┴┴ └┘ ┴ └──────────┘ ┴┴ └┘ ┴┴
st └───────────────────┘└──────────────────┘└──────────────────────┘└┘
531
532 @[simp] theorem join_cons (s : wseq α) (S) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘ └──┘
533 join (cons s S) = think (append s (join S)) :=
id └──┘ └──┘ ┴ ┴ ┴ └───┘ └────┘ ┴ └──┘ ┴
src └──┘ └──┘ ┴ └───┘ └────┘ └──┘
typ └──┘ └──┘ ┴ ┴ ┴ └───┘ └────┘ ┴ └──┘ ┴
doc └──┘ └──┘ └───┘ └────┘ └──┘
534 by { simp [think, join], unfold functor.map, simp [join, cons, append] }
id └───┘ └──┘ └──┘ └──┘ └────┘
src └────┘└───┘└┘└──┘┴ └────────────────┘ └────┘└──┘└┘└──┘└┘└────┘└┘
typ └────┘└───┘└┘└──┘┴ └────────────────┘ └────┘└──┘└┘└──┘└┘└────┘└┘
doc └────┘└───┘└┘└──┘┴ └────────────────┘ └────┘└──┘└┘└──┘└┘└────┘└┘
txt └────┘ └┘ ┴ └────────────────┘ └────┘ └┘ └┘ └┘
par └────┘ └┘ ┴ └────────────────┘ └────┘ └┘ └┘ └┘
pid ┴┴ └┘ ┴ └──────────┘ ┴┴ └┘ └┘ ┴┴
st └───────────────────┘└──────────────────┘└──────────────────────────┘└┘
535
536 @[simp] theorem nil_append (s : wseq α) : append nil s = s := seq.nil_append _
id └──┘ ┴ └────┘ └─┘ ┴ ┴ ┴ └────────────┘
src └──┘ └────┘ └─┘ ┴ └────────────┘
typ └──┘ ┴ └────┘ └─┘ ┴ ┴ ┴ └────────────┘
doc └──┘ └──┘ └────┘ └─┘
537
538 @[simp] theorem cons_append (a : α) (s t) :
id ┴
typ ┴
doc └──┘
539 append (cons a s) t = cons a (append s t) := seq.cons_append _ _ _
id └────┘ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └─────────────┘
src └────┘ └──┘ ┴ └──┘ └────┘ └─────────────┘
typ └────┘ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └─────────────┘
doc └────┘ └──┘ └──┘ └────┘
540
541 @[simp] theorem think_append (s t : wseq α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘ └──┘
542 append (think s) t = think (append s t) := seq.cons_append _ _ _
id └────┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ └─────────────┘
src └────┘ └───┘ ┴ └───┘ └────┘ └─────────────┘
typ └────┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ └─────────────┘
doc └────┘ └───┘ └───┘ └────┘
543
544 @[simp] theorem append_nil (s : wseq α) : append s nil = s := seq.append_nil _
id └──┘ ┴ └────┘ ┴ └─┘ ┴ ┴ └────────────┘
src └──┘ └────┘ └─┘ ┴ └────────────┘
typ └──┘ ┴ └────┘ ┴ └─┘ ┴ ┴ └────────────┘
doc └──┘ └──┘ └────┘ └─┘
545
546 @[simp] theorem append_assoc (s t u : wseq α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘ └──┘
547 append (append s t) u = append s (append t u) := seq.append_assoc _ _ _
id └────┘ └────┘ ┴ ┴ ┴ ┴ └────┘ ┴ └────┘ ┴ ┴ └──────────────┘
src └────┘ └────┘ ┴ └────┘ └────┘ └──────────────┘
typ └────┘ └────┘ ┴ ┴ ┴ ┴ └────┘ ┴ └────┘ ┴ ┴ └──────────────┘
doc └────┘ └────┘ └────┘ └────┘
548
549 @[simp] def tail.aux : option (α × wseq α) → computation (option (α × wseq α))
id └────┘ ┴ ┴ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
src └────┘ ┴ └──┘ └─────────┘ └────┘ ┴ └──┘
typ └────┘ ┴ ┴ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘ └─────────┘ └──┘
550 | none := return none
id └──┘ └────┘ └──┘
src └──┘ └────┘ └──┘
typ └──┘ └────┘ └──┘
doc └────┘
551 | (some (a, s)) := destruct s
id └──┘ ┴ ┴ └──────┘
src └──┘ ┴ └──────┘
typ └──┘ ┴ ┴ └──────┘
doc └──────┘
552
553 theorem destruct_tail (s : wseq α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
554 destruct (tail s) = destruct s >>= tail.aux :=
id └──────┘ └──┘ ┴ ┴ └──────┘ ┴ └─┘ └──────┘
src └──────┘ └──┘ ┴ └──────┘ └─┘ └──────┘
typ └──────┘ └──┘ ┴ ┴ └──────┘ ┴ └─┘ └──────┘
doc └──────┘ └──┘ └──────┘
555 begin
st └─────
556 dsimp [tail], simp, rw [← bind_pure_comp_eq_map, is_lawful_monad.bind_assoc],
id └──┘ └───────────────────┘ └────────────────────────┘
src └─────┘└──┘┴ └──┘ └────┘└───────────────────┘└┘└────────────────────────┘┴
typ └─────┘└──┘┴ └──┘ └────┘└───────────────────┘└┘└────────────────────────┘┴
doc └─────┘└──┘┴ └──┘ └────┘ └┘ ┴
txt └─────┘ ┴ └──┘ └────┘ └┘ ┴
par └─────┘ ┴ └──┘ └────┘ └┘ ┴
pid ┴┴ ┴ └──┘ └┘ ┴
st ─────────────┘└────┘└───────────────────────────┘└──────────────────────────┘└──
557 apply congr_arg, funext o,
id └───────┘
src └────┘└───────┘ └──────┘
typ └────┘└───────┘ └──────┘
doc └────┘ └──────┘
txt └────┘ └──────┘
par └────┘ └──────┘
pid ┴ └┘
st ────────────────┘└────────┘└─
558 rcases o with _|⟨a, s⟩;
id ┴
src └─────┘ └────────────┘
typ └─────┘┴└────────────┘
doc └─────┘ └────────────┘
txt └─────┘ └────────────┘
par └─────┘ └────────────┘
pid ┴ └────────────┘
st ──────────────────────────
559 apply (@pure_bind computation _ _ _ _ _ _).trans _; simp
id └───────┘ └─────────┘
src └────┘ └───────┘┴└─────────┘└───────────────────┘ └───┘
typ └────┘ └───────┘┴└─────────┘└───────────────────┘ └───┘
doc └────┘ ┴└─────────┘└───────────────────┘ └───┘
txt └────┘ ┴ └───────────────────┘ └───┘
par └────┘ ┴ └───────────────────┘ └───┘
pid ┴ ┴ └───────────────────┘ ┴
st ──────────────────────────────────────────────────────────┘
560 end
st └─┘
561
562 @[simp] def drop.aux : ℕ → option (α × wseq α) → computation (option (α × wseq α))
id ┴ ┴ └────┘ ┴ ┴ └──┘ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
src ┴ └────┘ ┴ └──┘ └─────────┘ └────┘ ┴ └──┘
typ ┴ ┴ └────┘ ┴ ┴ └──┘ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘ └─────────┘ └──┘
563 | 0 := return
id └────┘
src └────┘
typ └────┘
doc └────┘
564 | (n+1) := λ a, tail.aux a >>= drop.aux n
id ┴┴ ┴ └──────┘ ┴ └─┘ └──────┘
src ┴ └──────┘ └─┘
typ ┴┴ ┴ └──────┘ ┴ └─┘ └──────┘
565
566 theorem drop.aux_none : ∀ n, @drop.aux α n none = return none
id ┴ └──────┘ ┴ ┴ └──┘ ┴ └────┘ └──┘
src └──────┘ └──┘ ┴ └────┘ └──┘
typ ┴ └──────┘ ┴ ┴ └──┘ ┴ └────┘ └──┘
doc └────┘
567 | 0 := rfl
id └─┘
src └─┘
typ └─┘
568 | (n+1) := show computation.bind (return none) (drop.aux n) = return none,
id ┴┴ └──────────────┘ └────┘ └──┘ └──────┘ ┴ └────┘ └──┘
src ┴ └──────────────┘ └────┘ └──┘ └──────┘ ┴ └────┘ └──┘
typ ┴┴ └──────────────┘ └────┘ └──┘ └──────┘ ┴ └────┘ └──┘
doc └──────────────┘ └────┘ └────┘
569 by rw [ret_bind, drop.aux_none]
id └──────┘ └───────────┘
src └──┘└──────┘└┘ └─
typ └──┘└──────┘└┘└───────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └───────────┘└─────────────┘┴└
570
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
571 theorem destruct_dropn :
572 ∀ (s : wseq α) n, destruct (drop s n) = destruct s >>= drop.aux n
id ┴ └──┘ ┴ ┴ └──────┘ └──┘ ┴ ┴ ┴ └──────┘ ┴ └─┘ └──────┘ ┴
src └──┘ └──────┘ └──┘ ┴ └──────┘ └─┘ └──────┘
typ ┴ └──┘ ┴ ┴ └──────┘ └──┘ ┴ ┴ ┴ └──────┘ ┴ └─┘ └──────┘ ┴
doc └──┘ └──────┘ └──┘ └──────┘
573 | s 0 := (bind_ret' _).symm
id └───────┘ └──┘
src └───────┘ └──┘
typ └───────┘ └──┘
574 | s (n+1) := by rw [← dropn_tail, destruct_dropn _ n,
id ┴ └────────┘ └────────────┘ ┴
src ┴ └────┘└────────┘└┘ └─┘ └─
typ ┴ └────┘└────────┘└┘└────────────┘└─┘┴└─
doc └────┘ └┘ └─┘ └─
txt └────┘ └┘ └─┘ └─
par └────┘ └┘ └─┘ └─
pid └──┘ └┘ └─┘ └─
st └───────────────┘└──────────────────┘└─
575 destruct_tail, is_lawful_monad.bind_assoc]; refl
id └───────────┘ └────────────────────────┘
src ─┘└───────────┘└┘└────────────────────────┘┴ └────
typ ─┘└───────────┘└┘└────────────────────────┘┴ └────
doc ─┘ └┘ ┴ └────
txt ─┘ └┘ ┴ └────
par ─┘ └┘ ┴ └────
pid ─┘ └┘ ┴ └
st ──────────────┘└──────────────────────────┘┴└──────
576
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
577 theorem head_terminates_of_head_tail_terminates (s : wseq α) [T : terminates (head (tail s))] :
id └──┘ ┴ └────────┘ └──┘ └──┘ ┴
src └──┘ └────────┘ └──┘ └──┘
typ └──┘ ┴ └────────┘ └──┘ └──┘ ┴
doc └──┘ └────────┘ └──┘ └──┘
578 terminates (head s) :=
id └────────┘ └──┘ ┴
src └────────┘ └──┘
typ └────────┘ └──┘ ┴
doc └────────┘ └──┘
579 (head_terminates_iff _).2 $ begin
id └─────────────────┘ ┴
src └─────────────────┘ ┴
typ └─────────────────┘ ┴
st └─────
580 cases (head_terminates_iff _).1 T with a h,
id └─────────────────┘ ┴
src └────┘ └─────────────────┘└────┘ └───────┘
typ └────┘ └─────────────────┘└────┘┴└───────┘
doc └────┘ └────┘ └───────┘
txt └────┘ └────┘ └───────┘
par └────┘ └────┘ └───────┘
pid ┴ └────┘ └───────┘
st ───────────────────────────────────────────┘└─
581 simp [tail] at h,
id └──┘
src └────┘└──┘└────┘
typ └────┘└──┘└────┘
doc └────┘└──┘└────┘
txt └────┘ └────┘
par └────┘ └────┘
pid ┴┴ ┴┴└──┘
st ─────────────────┘└─
582 rcases exists_of_mem_bind h with ⟨s', h1, h2⟩,
id └────────────────┘ ┴
src └─────┘└────────────────┘┴ └────────────────┘
typ └─────┘└────────────────┘┴┴└────────────────┘
doc └─────┘ ┴ └────────────────┘
txt └─────┘ ┴ └────────────────┘
par └─────┘ ┴ └────────────────┘
pid ┴ ┴ └────────────────┘
st ──────────────────────────────────────────────┘└─
583 unfold functor.map at h1,
src └──────────────────────┘
typ └──────────────────────┘
doc └──────────────────────┘
txt └──────────────────────┘
par └──────────────────────┘
pid └──────────┘└────┘
st ─────────────────────────┘└─
584 exact let ⟨t, h3, h4⟩ := exists_of_mem_map h1 in terminates_of_mem h3
id └┘ └───────────────┘ └┘ └───────────────┘
src └────┘ ┴ └┘ └┘ └───┘└───────────────┘┴ └──┘└───────────────┘┴ ┴
typ └────┘ ┴ └┘└┘└┘ └───┘└───────────────┘┴└┘└──┘└───────────────┘┴ ┴
doc └────┘ ┴ └┘ └┘ └───┘ ┴ └──┘ ┴ ┴
txt └────┘ ┴ └┘ └┘ └───┘ ┴ └──┘ ┴ ┴
par └────┘ ┴ └┘ └┘ └───┘ ┴ └──┘ ┴ ┴
pid ┴ ┴ └┘ └┘ └───┘ ┴ └──┘ ┴ ┴
st ───────────────────────────────────────────────────────────────────────┘
585 end
st └─┘
586
587 theorem destruct_some_of_destruct_tail_some {s : wseq α} {a}
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
588 (h : some a ∈ destruct (tail s)) : ∃ a', some a' ∈ destruct s :=
id └──┘ ┴ ┴ └──────┘ └──┘ ┴ ┴ └┘┴ └──┘ └┘ ┴ └──────┘ ┴
src └──┘ ┴ └──────┘ └──┘ ┴ ┴ └──┘ ┴ └──────┘
typ └──┘ ┴ ┴ └──────┘ └──┘ ┴ ┴ └┘┴ └──┘ └┘ ┴ └──────┘ ┴
doc └──────┘ └──┘ └──────┘
589 begin
st └─────
590 unfold tail functor.map at h, simp at h,
src └──────────────────────────┘ └───────┘
typ └──────────────────────────┘ └───────┘
doc └──────────────────────────┘ └───────┘
txt └──────────────────────────┘ └───────┘
par └──────────────────────────┘ └───────┘
pid └───────────────┘└───┘ ┴└──┘
st ─────────────────────────────┘└─────────┘└─
591 rcases exists_of_mem_bind h with ⟨t, tm, td⟩, clear h,
id └────────────────┘ ┴
src └─────┘└────────────────┘┴ └───────────────┘ └─────┘
typ └─────┘└────────────────┘┴┴└───────────────┘ └─────┘
doc └─────┘ ┴ └───────────────┘ └─────┘
txt └─────┘ ┴ └───────────────┘ └─────┘
par └─────┘ ┴ └───────────────┘ └─────┘
pid ┴ ┴ └───────────────┘ └┘
st ─────────────────────────────────────────────┘└───────┘└─
592 rcases exists_of_mem_map tm with ⟨t', ht', ht2⟩, clear tm,
id └───────────────┘ └┘
src └─────┘└───────────────┘┴ └──────────────────┘ └──────┘
typ └─────┘└───────────────┘┴└┘└──────────────────┘ └──────┘
doc └─────┘ ┴ └──────────────────┘ └──────┘
txt └─────┘ ┴ └──────────────────┘ └──────┘
par └─────┘ ┴ └──────────────────┘ └──────┘
pid ┴ ┴ └──────────────────┘ └─┘
st ────────────────────────────────────────────────┘└────────┘└─
593 cases t' with t'; rw ←ht2 at td; simp at td,
id └┘ └─┘
src └────┘ └──────┘ └──┘ └────┘ └────────┘
typ └────┘└┘└──────┘ └──┘└─┘└────┘ └────────┘
doc └────┘ └──────┘ └──┘ └────┘ └────────┘
txt └────┘ └──────┘ └──┘ └────┘ └────────┘
par └────┘ └──────┘ └──┘ └────┘ └────────┘
pid ┴ └──────┘ └┘ └────┘ ┴└───┘
st ────────────────────────────────────────────┘└─
594 { have := mem_unique td (ret_mem _), contradiction },
id └────────┘ └┘ └─────┘
src └──────┘└────────┘┴ ┴ └─────┘└─┘ └────────────┘
typ └──────┘└────────┘┴└┘┴ └─────┘└─┘ └────────────┘
doc └──────┘ ┴ ┴ └─┘ └────────────┘
txt └──────┘ ┴ ┴ └─┘ └────────────┘
par └──────┘ ┴ ┴ └─┘ └────────────┘
pid └───┘└─┘ ┴ ┴ └─┘ ┴
st ───┘└───────────────────────────────┘└──────────────┘└┘└
595 { exact ⟨_, ht'⟩ }
id └─┘
src └────┘ └─┘ └┘
typ └────┘ └─┘└─┘└┘
doc └────┘ └─┘ └┘
txt └────┘ └─┘ └┘
par └────┘ └─┘ └┘
pid ┴ └─┘ ┴┴
st ──────────────────┘└─
596 end
st ──┘
597
598 theorem head_some_of_head_tail_some {s : wseq α} {a}
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
599 (h : some a ∈ head (tail s)) : ∃ a', some a' ∈ head s :=
id └──┘ ┴ ┴ └──┘ └──┘ ┴ ┴ └┘┴ └──┘ └┘ ┴ └──┘ ┴
src └──┘ ┴ └──┘ └──┘ ┴ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └──┘ └──┘ ┴ ┴ └┘┴ └──┘ └┘ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘
600 begin
st └─────
601 unfold head at h,
src └──────────────┘
typ └──────────────┘
doc └──────────────┘
txt └──────────────┘
par └──────────────┘
pid └───┘└───┘
st ─────────────────┘└─
602 rcases exists_of_mem_map h with ⟨o, md, e⟩, clear h,
id └───────────────┘ ┴
src └─────┘└───────────────┘┴ └──────────────┘ └─────┘
typ └─────┘└───────────────┘┴┴└──────────────┘ └─────┘
doc └─────┘ ┴ └──────────────┘ └─────┘
txt └─────┘ ┴ └──────────────┘ └─────┘
par └─────┘ ┴ └──────────────┘ └─────┘
pid ┴ ┴ └──────────────┘ └┘
st ───────────────────────────────────────────┘└───────┘└─
603 cases o with o; injection e with h', clear e h',
id ┴ ┴
src └────┘ └─────┘ └────────┘ └──────┘ └────────┘
typ └────┘┴└─────┘ └────────┘┴└──────┘ └────────┘
doc └────┘ └─────┘ └────────┘ └──────┘ └────────┘
txt └────┘ └─────┘ └────────┘ └──────┘ └────────┘
par └────┘ └─────┘ └────────┘ └──────┘ └────────┘
pid ┴ └─────┘ ┴ └──────┘ └───┘
st ────────────────────────────────────┘└──────────┘└─
604 cases destruct_some_of_destruct_tail_some md with a am,
id └─────────────────────────────────┘ └┘
src └────┘└─────────────────────────────────┘┴ └────────┘
typ └────┘└─────────────────────────────────┘┴└┘└────────┘
doc └────┘ ┴ └────────┘
txt └────┘ ┴ └────────┘
par └────┘ ┴ └────────┘
pid ┴ ┴ └────────┘
st ───────────────────────────────────────────────────────┘└─
605 exact ⟨_, mem_map ((<$>) (@prod.fst α (wseq α))) am⟩
id └─────┘ ┴ └──────┘ └──┘ ┴ └┘
src └────┘ └─┘└─────┘┴ ┴└───┘ └──────┘┴ ┴ └──┘┴ └──┘ └┘
typ └────┘ └─┘└─────┘┴ ┴└───┘ └──────┘┴ ┴ └──┘┴┴└──┘└┘└┘
doc └────┘ └─┘ ┴ └───┘ ┴ ┴ └──┘┴ └──┘ └┘
txt └────┘ └─┘ ┴ └───┘ ┴ ┴ ┴ └──┘ └┘
par └────┘ └─┘ ┴ └───┘ ┴ ┴ ┴ └──┘ └┘
pid ┴ └─┘ ┴ └───┘ ┴ ┴ ┴ └──┘ ┴┴
st ──────────────────────────────────────────────────────┘
606 end
st └─┘
607
608 theorem head_some_of_nth_some {s : wseq α} {a n}
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
609 (h : some a ∈ nth s n) : ∃ a', some a' ∈ head s :=
id └──┘ ┴ ┴ └─┘ ┴ ┴ ┴ └┘┴ └──┘ └┘ ┴ └──┘ ┴
src └──┘ ┴ └─┘ ┴ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴ └┘┴ └──┘ └┘ ┴ └──┘ ┴
doc └─┘ └──┘
610 begin
st └─────
611 revert a, induction n with n IH; intros,
id ┴
src └──────┘ └────────┘ └────────┘ └────┘
typ └──────┘ └────────┘┴└────────┘ └────┘
doc └──────┘ └────────┘ └────────┘ └────┘
txt └──────┘ └────────┘ └────────┘ └────┘
par └──────┘ └────────┘ └────────┘ └────┘
pid └┘ ┴ ┴└───────┘
st ─────────┘└─────────────────────────────┘└─
612 exacts [⟨_, h⟩, let ⟨a', h'⟩ := head_some_of_head_tail_some h in IH h']
id ┴ └┘ └─────────────────────────┘ ┴ └┘
src └──────┘ └─┘ └─┘ ┴ └┘ └───┘└─────────────────────────┘┴ └──┘ ┴ └┘
typ └──────┘ └─┘┴└─┘ ┴ └┘└┘└───┘└─────────────────────────┘┴┴└──┘└┘┴ └┘
doc └──────┘ └─┘ └─┘ ┴ └┘ └───┘ ┴ └──┘ ┴ └┘
txt └──────┘ └─┘ └─┘ ┴ └┘ └───┘ ┴ └──┘ ┴ └┘
par └──────┘ └─┘ └─┘ ┴ └┘ └───┘ ┴ └──┘ ┴ └┘
pid └┘ └─┘ └─┘ ┴ └┘ └───┘ ┴ └──┘ ┴ ┴┴
st ─────────────────────────────────────────────────────────────────────────┘
613 end
st └─┘
614
615 instance productive_tail (s : wseq α) [productive s] : productive (tail s) :=
id └──┘ ┴ └────────┘ ┴ └────────┘ └──┘ ┴
src └──┘ └────────┘ └────────┘ └──┘
typ └──┘ ┴ └────────┘ ┴ └────────┘ └──┘ ┴
doc └──┘ └────────┘ └────────┘ └──┘
616 λ n, by rw [nth_tail]; apply_instance
id ┴ └──────┘
src └──┘└──────┘┴ └──────────────
typ ┴ └──┘└──────┘┴ └──────────────
doc └──┘ ┴ └──────────────
txt └──┘ ┴ └──────────────
par └──┘ ┴ └──────────────
pid └┘ ┴ └
st └───────────┘┴└────────────────
617
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
618 instance productive_dropn (s : wseq α) [productive s] (n) : productive (drop s n) :=
id └──┘ ┴ └────────┘ ┴ └────────┘ └──┘ ┴ ┴
src └──┘ └────────┘ └────────┘ └──┘
typ └──┘ ┴ └────────┘ ┴ └────────┘ └──┘ ┴ ┴
doc └──┘ └────────┘ └────────┘ └──┘
619 λ m, by rw [←nth_add]; apply_instance
id ┴ └─────┘
src └───┘└─────┘┴ └──────────────
typ ┴ └───┘└─────┘┴ └──────────────
doc └───┘ ┴ └──────────────
txt └───┘ ┴ └──────────────
par └───┘ ┴ └──────────────
pid └─┘ ┴ └
st └───────────┘┴└────────────────
620
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
621 /-- Given a productive weak sequence, we can collapse all the `think`s to
622 produce a sequence. -/
623 def to_seq (s : wseq α) [productive s] : seq α :=
id └──┘ ┴ └────────┘ ┴ └─┘ ┴
src └──┘ └────────┘ └─┘
typ └──┘ ┴ └────────┘ ┴ └─┘ ┴
doc └──┘ └────────┘ └─┘
624 ⟨λ n, (nth s n).get, λn h,
id ┴ └─┘ ┴ ┴ └─┘ ┴ ┴
src └─┘ └─┘
typ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴
doc └─┘ └─┘
625 begin
st └─────
626 cases e : computation.get (nth s (n + 1)), {assumption},
id └─────────────┘ └─┘ ┴ ┴ ┴
src └────┘ └─┘└─────────────┘┴ └─┘┴ ┴ ┴┴└──┘ └────────┘
typ └────┘ └─┘└─────────────┘┴ └─┘┴┴┴ ┴┴┴└──┘ └────────┘
doc └────┘ └─┘└─────────────┘┴ └─┘┴ ┴ ┴ └──┘ └────────┘
txt └────┘ └─┘ ┴ ┴ ┴ ┴ └──┘ └────────┘
par └────┘ └─┘ ┴ ┴ ┴ ┴ └──┘ └────────┘
pid ┴ └─┘ ┴ ┴ ┴ ┴ └──┘
st ──────────────────────────────────────────┘└───────────┘└┘└
627 have := mem_of_get_eq _ e,
id └───────────┘ ┴
src └──────┘└───────────┘└─┘
typ └──────┘└───────────┘└─┘┴
doc └──────┘ └─┘
txt └──────┘ └─┘
par └──────┘ └─┘
pid └───┘└─┘ └─┘
st ──────────────────────────┘└─
628 simp [nth] at this h, cases head_some_of_head_tail_some this with a' h',
id └─┘ └─────────────────────────┘ └──┘
src └────┘└─┘└─────────┘ └────┘└─────────────────────────┘┴ └─────────┘
typ └────┘└─┘└─────────┘ └────┘└─────────────────────────┘┴└──┘└─────────┘
doc └────┘└─┘└─────────┘ └────┘ ┴ └─────────┘
txt └────┘ └─────────┘ └────┘ ┴ └─────────┘
par └────┘ └─────────┘ └────┘ ┴ └─────────┘
pid ┴┴ ┴┴└───────┘ ┴ ┴ └─────────┘
st ─────────────────────┘└─────────────────────────────────────────────────┘└─
629 have := mem_unique h' (@mem_of_get_eq _ _ _ _ h),
id └────────┘ └┘ └───────────┘ ┴
src └──────┘└────────┘┴ ┴ └───────────┘└───────┘ ┴
typ └──────┘└────────┘┴└┘┴ └───────────┘└───────┘┴┴
doc └──────┘ ┴ ┴ └───────┘ ┴
txt └──────┘ ┴ ┴ └───────┘ ┴
par └──────┘ ┴ ┴ └───────┘ ┴
pid └───┘└─┘ ┴ ┴ └───────┘ ┴
st ─────────────────────────────────────────────────┘└─
630 contradiction
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid ┴
st ───────────────┘
631 end⟩
st └─┘
632
633 theorem nth_terminates_le {s : wseq α} {m n} (h : m ≤ n) : terminates (nth s n) → terminates (nth s m) :=
id └──┘ ┴ ┴ ┴ ┴ └────────┘ └─┘ ┴ ┴ └────────┘ └─┘ ┴ ┴
src └──┘ ┴ └────────┘ └─┘ └────────┘ └─┘
typ └──┘ ┴ ┴ ┴ ┴ └────────┘ └─┘ ┴ ┴ └────────┘ └─┘ ┴ ┴
doc └──┘ └────────┘ └─┘ └────────┘ └─┘
634 by induction h with m' h IH; [exact id,
id ┴ ┴ └┘
src └────────┘ └───────────┘ ┴└────┘└┘
typ └────────┘┴└───────────┘ ┴└────┘└┘
doc └────────┘ └───────────┘ └────┘
txt └────────┘ └───────────┘ └────┘
par └────────┘ └───────────┘ └────┘
pid ┴ ┴└──────────┘ ┴
st └─────────────────────────────────────
635 exact λ T, IH (@head_terminates_of_head_tail_terminates _ _ T)]
id └┘ └─────────────────────────────────────┘
src └────┘ └──┘ ┴ └─────────────────────────────────────┘└───┘ ┴
typ └────┘ └──┘└┘┴ └─────────────────────────────────────┘└───┘ ┴
doc └────┘ └──┘ ┴ └───┘ ┴
txt └────┘ └──┘ ┴ └───┘ ┴
par └────┘ └──┘ ┴ └───┘ ┴
pid ┴ └──┘ ┴ └───┘ ┴
st ────────────────────────────────────────────────────────────────┘
636
637 theorem head_terminates_of_nth_terminates {s : wseq α} {n} : terminates (nth s n) → terminates (head s) :=
id └──┘ ┴ └────────┘ └─┘ ┴ ┴ └────────┘ └──┘ ┴
src └──┘ └────────┘ └─┘ └────────┘ └──┘
typ └──┘ ┴ └────────┘ └─┘ ┴ ┴ └────────┘ └──┘ ┴
doc └──┘ └────────┘ └─┘ └────────┘ └──┘
638 nth_terminates_le (nat.zero_le n)
id └───────────────┘ └─────────┘ ┴
src └───────────────┘ └─────────┘
typ └───────────────┘ └─────────┘ ┴
639
640 theorem destruct_terminates_of_nth_terminates {s : wseq α} {n} (T : terminates (nth s n)) : terminates (destruct s) :=
id └──┘ ┴ └────────┘ └─┘ ┴ ┴ └────────┘ └──────┘ ┴
src └──┘ └────────┘ └─┘ └────────┘ └──────┘
typ └──┘ ┴ └────────┘ └─┘ ┴ ┴ └────────┘ └──────┘ ┴
doc └──┘ └────────┘ └─┘ └────────┘ └──────┘
641 (head_terminates_iff _).1 $ head_terminates_of_nth_terminates T
id └─────────────────┘ ┴ └───────────────────────────────┘ ┴
src └─────────────────┘ ┴ └───────────────────────────────┘
typ └─────────────────┘ ┴ └───────────────────────────────┘ ┴
642
643 theorem mem_rec_on {C : wseq α → Prop} {a s} (M : a ∈ s)
id └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴
doc └──┘
644 (h1 : ∀ b s', (a = b ∨ C s') → C (cons b s'))
id ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴ └┘
src ┴ ┴ └──┘
typ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴ └┘
doc └──┘
645 (h2 : ∀ s, C s → C (think s)) : C s :=
id ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └───┘
typ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └───┘
646 begin
st └─────
647 apply seq.mem_rec_on M,
id └────────────┘ ┴
src └────┘└────────────┘┴
typ └────┘└────────────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────────┘└─
648 intros o s' h, cases o with b,
id ┴
src └───────────┘ └────┘ └─────┘
typ └───────────┘ └────┘┴└─────┘
doc └───────────┘ └────┘ └─────┘
txt └───────────┘ └────┘ └─────┘
par └───────────┘ └────┘ └─────┘
pid └─────┘ ┴ └─────┘
st ──────────────┘└──────────────┘└─
649 { apply h2, cases h, {contradiction}, {assumption} },
id ┴
src └────┘ └────┘ └───────────┘ └────────┘
typ └────┘ └────┘┴ └───────────┘ └────────┘
doc └────┘ └────┘ └───────────┘ └────────┘
txt └────┘ └────┘ └───────────┘ └────────┘
par └────┘ └────┘ └───────────┘ └────────┘
pid ┴ ┴
st ───┘└──────┘└───────┘└──────────────┘└┘└──────────┘└──┘└
650 { apply h1, apply or.imp_left _ h, intro h, injection h }
id └─────────┘ ┴ ┴
src └────┘ └────┘└─────────┘└─┘ └─────┘ └────────┘ ┴
typ └────┘ └────┘└─────────┘└─┘┴ └─────┘ └────────┘┴┴
doc └────┘ └────┘ └─┘ └─────┘ └────────┘ ┴
txt └────┘ └────┘ └─┘ └─────┘ └────────┘ ┴
par └────┘ └────┘ └─┘ └─────┘ └────────┘ ┴
pid ┴ ┴ └─┘ └┘ ┴ ┴
st ───────────┘└─────────────────────┘└───────┘└────────────┘└─
651 end
st ──┘
652
653 @[simp] theorem mem_think (s : wseq α) (a) : a ∈ think s ↔ a ∈ s :=
id └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └───┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘ └───┘
654 begin
st └─────
655 cases s with f al,
id ┴
src └────┘ └────────┘
typ └────┘┴└────────┘
doc └────┘ └────────┘
txt └────┘ └────────┘
par └────┘ └────────┘
pid ┴ └────────┘
st ──────────────────┘└─
656 change some (some a) ∈ some none :: f ↔ some (some a) ∈ f,
id ┴ └──┘ └┘ └──┘ ┴ ┴
src └─────┘ ┴ ┴ └┘┴┴ ┴└──┘┴└┘┴ ┴ ┴ ┴ └──┘┴ └┘ ┴
typ └─────┘ ┴ ┴ └┘┴┴ ┴└──┘┴└┘┴ ┴ ┴ ┴ └──┘┴┴└┘ ┴┴
doc └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴
txt └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴
par └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴
pid ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴
st ──────────────────────────────────────────────────────────┘└─
657 constructor; intro h,
src └─────────┘ └─────┘
typ └─────────┘ └─────┘
doc └─────────┘ └─────┘
txt └─────────┘ └─────┘
par └─────────┘ └─────┘
pid └┘
st ─────────────────────┘└─
658 { apply (stream.eq_or_mem_of_mem_cons h).resolve_left,
id └──────────────────────────┘ ┴
src └────┘ └──────────────────────────┘┴ └────────────┘
typ └────┘ └──────────────────────────┘┴┴└────────────┘
doc └────┘ ┴ └────────────┘
txt └────┘ ┴ └────────────┘
par └────┘ ┴ └────────────┘
pid ┴ ┴ └───────────┘┴
st ───┘└─────────────────────────────────────────────────┘└─
659 intro, injections },
src └───┘ └─────────┘
typ └───┘ └─────────┘
doc └───┘ └─────────┘
txt └───┘ └─────────┘
par └───┘ └─────────┘
pid ┴
st ────────┘└───────────┘└┘└
660 { apply stream.mem_cons_of_mem _ h }
id └────────────────────┘ ┴
src └────┘└────────────────────┘└─┘ ┴
typ └────┘└────────────────────┘└─┘┴┴
doc └────┘ └─┘ ┴
txt └────┘ └─┘ ┴
par └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ────────────────────────────────────┘└─
661 end
st ──┘
662
663 theorem eq_or_mem_iff_mem {s : wseq α} {a a' s'} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
664 some (a', s') ∈ destruct s → (a ∈ s ↔ a = a' ∨ a ∈ s') :=
id └──┘ ┴└┘ └┘ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴
typ └──┘ ┴└┘ └┘ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──────┘
665 begin
st └─────
666 generalize e : destruct s = c, intro h,
id └──────┘ ┴
src └─────────────┘└──────┘┴ ┴ ┴ └─────┘
typ └─────────────┘└──────┘┴┴┴ ┴ └─────┘
doc └─────────────┘└──────┘┴ ┴ ┴ └─────┘
txt └─────────────┘ ┴ ┴ ┴ └─────┘
par └─────────────┘ ┴ ┴ ┴ └─────┘
pid └┘└┘┴ ┴ ┴ ┴ └┘
st ──────────────────────────────┘└───────┘└─
667 revert s, apply computation.mem_rec_on h _ (λ c IH, _); intro s;
id └────────────────────┘ ┴
src └──────┘ └────┘└────────────────────┘┴ └─┘ └───────┘ └─────┘
typ └──────┘ └────┘└────────────────────┘┴┴└─┘ └───────┘ └─────┘
doc └──────┘ └────┘ ┴ └─┘ └───────┘ └─────┘
txt └──────┘ └────┘ ┴ └─┘ └───────┘ └─────┘
par └──────┘ └────┘ ┴ └─┘ └───────┘ └─────┘
pid └┘ ┴ ┴ └─┘ └───────┘ └┘
st ─────────┘└────────────────────────────────────────────────────────
668 apply s.cases_on _ (λ x s, _) (λ s, _); intros m;
id └────────┘
src └────┘└────────┘└─┘ └───────┘ └────┘ └──────┘
typ └────┘└────────┘└─┘ └───────┘ └────┘ └──────┘
doc └────┘ └─┘ └───────┘ └────┘ └──────┘
txt └────┘ └─┘ └───────┘ └────┘ └──────┘
par └────┘ └─┘ └───────┘ └────┘ └──────┘
pid ┴ └─┘ └───────┘ └────┘ └┘
st ────────────────────────────────────────────────────
669 have := congr_arg computation.destruct m; simp at this;
id └───────┘ └──────────────────┘ ┴
src └──────┘└───────┘┴└──────────────────┘┴ └──────────┘
typ └──────┘└───────┘┴└──────────────────┘┴┴ └──────────┘
doc └──────┘ ┴└──────────────────┘┴ └──────────┘
txt └──────┘ ┴ ┴ └──────────┘
par └──────┘ ┴ ┴ └──────────┘
pid └───┘└─┘ ┴ ┴ ┴└─────┘
st ──────────────────────────────────────────────────────────
670 cases this with i1 i2,
id └──┘
src └────┘ └─────────┘
typ └────┘└──┘└─────────┘
doc └────┘ └─────────┘
txt └────┘ └─────────┘
par └────┘ └─────────┘
pid ┴ └─────────┘
st ──────────────────────┘└─
671 { rw [i1, i2],
id └┘ └┘
src └──┘ └┘ ┴
typ └──┘└┘└┘└┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ───┘└────┘└──┘└──
672 cases s' with f al,
id └┘
src └────┘ └────────┘
typ └────┘└┘└────────┘
doc └────┘ └────────┘
txt └────┘ └────────┘
par └────┘ └────────┘
pid ┴ └────────┘
st ─────────────────────┘└─
673 unfold cons has_mem.mem wseq.mem seq.mem seq.cons, simp,
src └───────────────────────────────────────────────┘ └──┘
typ └───────────────────────────────────────────────┘ └──┘
doc └───────────────────────────────────────────────┘ └──┘
txt └───────────────────────────────────────────────┘ └──┘
par └───────────────────────────────────────────────┘ └──┘
pid └─────────────────────────────────────────┘
st ────────────────────────────────────────────────────┘└────┘└─
674 have h_a_eq_a' : a = a' ↔ some (some a) = some (some a'), {simp},
id ┴ └──┘ └┘
src └───────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └──┘┴ ┴ └──┘
typ └───────────────┘ ┴ ┴ ┴ ┴ ┴ ┴┴└┘ ┴ ┴ └──┘┴└┘┴ └──┘
doc └───────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └──┘
txt └───────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └──┘
par └───────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └──┘
pid └────────────┘└─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴
st ───────────────────────────────────────────────────────────┘└─────┘└┘└
675 rw [h_a_eq_a'],
id └───────┘
src └──┘ ┴
typ └──┘└───────┘┴
doc └──┘ ┴
txt └──┘ ┴
par └──┘ ┴
pid └┘ ┴
st ────────────────┘└──
676 refine ⟨stream.eq_or_mem_of_mem_cons, λo, _⟩,
id └──────────────────────────┘
src └─────┘ └──────────────────────────┘└┘ └───┘
typ └─────┘ └──────────────────────────┘└┘ └───┘
doc └─────┘ └┘ └───┘
txt └─────┘ └┘ └───┘
par └─────┘ └┘ └───┘
pid ┴ └┘ └───┘
st ───────────────────────────────────────────────┘└─
677 { cases o with e m,
id ┴
src └────┘ └───────┘
typ └────┘┴└───────┘
doc └────┘ └───────┘
txt └────┘ └───────┘
par └────┘ └───────┘
pid ┴ └───────┘
st ─────────────────────┘└─
678 { rw e, apply stream.mem_cons },
id ┴ └─────────────┘
src └─┘ └────┘└─────────────┘┴
typ └─┘┴ └────┘└─────────────┘┴
doc └─┘ └────┘ ┴
txt └─┘ └────┘ ┴
par └─┘ └────┘ ┴
pid ┴ ┴ ┴
st ───────┘└──┘└──────────────────────┘└┘└
679 { exact stream.mem_cons_of_mem _ m } } },
id └────────────────────┘ ┴
src └────┘└────────────────────┘└─┘ ┴
typ └────┘└────────────────────┘└─┘┴┴
doc └────┘ └─┘ ┴
txt └────┘ └─┘ ┴
par └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ────────────────────────────────────────┘└────┘└
680 { simp, exact IH this }
id └┘ └──┘
src └──┘ └────┘ ┴ ┴
typ └──┘ └────┘└┘┴└──┘┴
doc └──┘ └────┘ ┴ ┴
txt └──┘ └────┘ ┴ ┴
par └──┘ └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───────┘└──────────────┘└─
681 end
st ──┘
682
683 @[simp] theorem mem_cons_iff (s : wseq α) (b) {a} : a ∈ cons b s ↔ a = b ∨ a ∈ s :=
id └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └──┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘ └──┘
684 eq_or_mem_iff_mem $ by simp [ret_mem]
id └───────────────┘ └─────┘
src └───────────────┘ └────┘└─────┘└─
typ └───────────────┘ └────┘└─────┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └───────────────
685
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
686 theorem mem_cons_of_mem {s : wseq α} (b) {a} (h : a ∈ s) : a ∈ cons b s :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘ ┴ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴
doc └──┘ └──┘
687 (mem_cons_iff _ _).2 (or.inr h)
id └──────────┘ ┴ └────┘ ┴
src └──────────┘ ┴ └────┘
typ └──────────┘ ┴ └────┘ ┴
688
689 theorem mem_cons (s : wseq α) (a) : a ∈ cons a s :=
id └──┘ ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴
doc └──┘ └──┘
690 (mem_cons_iff _ _).2 (or.inl rfl)
id └──────────┘ ┴ └────┘ └─┘
src └──────────┘ ┴ └────┘ └─┘
typ └──────────┘ ┴ └────┘ └─┘
691
692 theorem mem_of_mem_tail {s : wseq α} {a} : a ∈ tail s → a ∈ s :=
id └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └──┘ ┴
typ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘ └──┘
693 begin
st └─────
694 intro h, have := h, cases h with n e, revert s, simp [stream.nth],
id ┴ ┴ └────────┘
src └─────┘ └──────┘ └────┘ └───────┘ └──────┘ └────┘└────────┘┴
typ └─────┘ └──────┘┴ └────┘┴└───────┘ └──────┘ └────┘└────────┘┴
doc └─────┘ └──────┘ └────┘ └───────┘ └──────┘ └────┘ ┴
txt └─────┘ └──────┘ └────┘ └───────┘ └──────┘ └────┘ ┴
par └─────┘ └──────┘ └────┘ └───────┘ └──────┘ └────┘ ┴
pid └┘ └───┘└─┘ ┴ └───────┘ └┘ ┴┴ ┴
st ────────┘└─────────┘└────────────────┘└────────┘└─────────────────┘└─
695 induction n with n IH; intro s; apply s.cases_on _ (λx s, _) (λ s, _);
id ┴ └────────┘
src └────────┘ └────────┘ └─────┘ └────┘└────────┘└─┘ └──────┘ └────┘
typ └────────┘┴└────────┘ └─────┘ └────┘└────────┘└─┘ └──────┘ └────┘
doc └────────┘ └────────┘ └─────┘ └────┘ └─┘ └──────┘ └────┘
txt └────────┘ └────────┘ └─────┘ └────┘ └─┘ └──────┘ └────┘
par └────────┘ └────────┘ └─────┘ └────┘ └─┘ └──────┘ └────┘
pid ┴ ┴└───────┘ └┘ ┴ └─┘ └──────┘ └────┘
st ─────────────────────────────────────────────────────────────────────────
696 repeat{simp}; intros m e; injections,
src └─────┘└──┘┴ └────────┘ └────────┘
typ └─────┘└──┘┴ └────────┘ └────────┘
doc └─────┘└──┘┴ └────────┘ └────────┘
txt └─────┘└──┘┴ └────────┘ └────────┘
par └─────┘└──┘┴ └────────┘ └────────┘
pid └────┘ └──┘
st ──────────┘└────┘└─────────────────────┘└─
697 { exact or.inr m },
id └────┘ ┴
src └────┘└────┘┴ ┴
typ └────┘└────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───┘└─────────────┘└┘└
698 { exact or.inr m },
id └────┘ ┴
src └────┘└────┘┴ ┴
typ └────┘└────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───┘└─────────────┘└┘└
699 { apply IH m, rw e, cases tail s, refl }
id └┘ ┴ ┴ └──┘ ┴
src └────┘ ┴ └─┘ └────┘└──┘┴ └───┘
typ └────┘└┘┴┴ └─┘┴ └────┘└──┘┴┴ └───┘
doc └────┘ ┴ └─┘ └────┘└──┘┴ └───┘
txt └────┘ ┴ └─┘ └────┘ ┴ └───┘
par └────┘ ┴ └─┘ └────┘ ┴ └───┘
pid ┴ ┴ ┴ ┴ ┴ ┴
st ─────────────┘└────┘└────────────┘└─────┘└─
700 end
st ──┘
701
702 theorem mem_of_mem_dropn {s : wseq α} {a} : ∀ {n}, a ∈ drop s n → a ∈ s
id └──┘ ┴ ┴┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └──┘ ┴
typ └──┘ ┴ ┴┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘
703 | 0 h := h
id ┴
typ ┴
704 | (n+1) h := @mem_of_mem_dropn n (mem_of_mem_tail h)
id ┴┴ ┴ └──────────────┘ └─────────────┘
src ┴ └─────────────┘
typ ┴┴ ┴ └──────────────┘ └─────────────┘
705
706 theorem nth_mem {s : wseq α} {a n} : some a ∈ nth s n → a ∈ s :=
id └──┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └─┘ ┴
typ └──┘ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─┘
707 begin
st └─────
708 revert s, induction n with n IH; intros s h,
id ┴
src └──────┘ └────────┘ └────────┘ └────────┘
typ └──────┘ └────────┘┴└────────┘ └────────┘
doc └──────┘ └────────┘ └────────┘ └────────┘
txt └──────┘ └────────┘ └────────┘ └────────┘
par └──────┘ └────────┘ └────────┘ └────────┘
pid └┘ ┴ ┴└───────┘ └──┘
st ─────────┘└─────────────────────────────────┘└─
709 { rcases exists_of_mem_map h with ⟨o, h1, h2⟩,
id └───────────────┘ ┴
src └─────┘└───────────────┘┴ └───────────────┘
typ └─────┘└───────────────┘┴┴└───────────────┘
doc └─────┘ ┴ └───────────────┘
txt └─────┘ ┴ └───────────────┘
par └─────┘ ┴ └───────────────┘
pid ┴ ┴ └───────────────┘
st ───┘└─────────────────────────────────────────┘└─
710 cases o with o; injection h2 with h',
id ┴ └┘
src └────┘ └─────┘ └────────┘ └──────┘
typ └────┘┴└─────┘ └────────┘└┘└──────┘
doc └────┘ └─────┘ └────────┘ └──────┘
txt └────┘ └─────┘ └────────┘ └──────┘
par └────┘ └─────┘ └────────┘ └──────┘
pid ┴ └─────┘ ┴ └──────┘
st ───────────────────────────────────────┘└─
711 cases o with a' s',
id ┴
src └────┘ └─────────┘
typ └────┘┴└─────────┘
doc └────┘ └─────────┘
txt └────┘ └─────────┘
par └────┘ └─────────┘
pid ┴ └─────────┘
st ─────────────────────┘└─
712 exact (eq_or_mem_iff_mem h1).2 (or.inl h'.symm) },
id └───────────────┘ └┘ └────┘ └─────┘
src └────┘ └───────────────┘┴ └──┘ └────┘┴└─────┘└┘
typ └────┘ └───────────────┘┴└┘└──┘ └────┘┴└─────┘└┘
doc └────┘ ┴ └──┘ ┴ └┘
txt └────┘ ┴ └──┘ ┴ └┘
par └────┘ ┴ └──┘ ┴ └┘
pid ┴ ┴ └──┘ ┴ ┴┴
st ───────────────────────────────────────────────────┘└┘└
713 { have := @IH (tail s), rw nth_tail at this,
id └┘ └──┘ ┴ └──────┘
src └──────┘ ┴ └──┘┴ ┴ └─┘└──────┘└──────┘
typ └──────┘ └┘┴ └──┘┴┴┴ └─┘└──────┘└──────┘
doc └──────┘ ┴ └──┘┴ ┴ └─┘ └──────┘
txt └──────┘ ┴ ┴ ┴ └─┘ └──────┘
par └──────┘ ┴ ┴ ┴ └─┘ └──────┘
pid └───┘└─┘ ┴ ┴ ┴ ┴ └──────┘
st ───────────────────────┘└───────────────────┘└─
714 exact mem_of_mem_tail (this h) }
id └─────────────┘ └──┘ ┴
src └────┘└─────────────┘┴ ┴ └┘
typ └────┘└─────────────┘┴ └──┘┴┴└┘
doc └────┘ ┴ ┴ └┘
txt └────┘ ┴ ┴ └┘
par └────┘ ┴ ┴ └┘
pid ┴ ┴ ┴ ┴┴
st ──────────────────────────────────┘└─
715 end
st ──┘
716
717 theorem exists_nth_of_mem {s : wseq α} {a} (h : a ∈ s) : ∃ n, some a ∈ nth s n :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴┴ └──┘ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ ┴ ┴ └──┘ ┴ └─┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴┴ └──┘ ┴ ┴ └─┘ ┴ ┴
doc └──┘ └─┘
718 begin
st └─────
719 apply mem_rec_on h,
id └────────┘ ┴
src └────┘└────────┘┴
typ └────┘└────────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────┘└─
720 { intros a' s' h, cases h with h h,
id ┴
src └────────────┘ └────┘ └───────┘
typ └────────────┘ └────┘┴└───────┘
doc └────────────┘ └────┘ └───────┘
txt └────────────┘ └────┘ └───────┘
par └────────────┘ └────┘ └───────┘
pid └──────┘ ┴ └───────┘
st ───┘└────────────┘└────────────────┘└─
721 { existsi 0, simp [nth], rw h, apply ret_mem },
id └─┘ ┴ └─────┘
src └───────┘ └────┘└─┘┴ └─┘ └────┘└─────┘┴
typ └───────┘ └────┘└─┘┴ └─┘┴ └────┘└─────┘┴
doc └───────┘ └────┘└─┘┴ └─┘ └────┘ ┴
txt └───────┘ └────┘ ┴ └─┘ └────┘ ┴
par └───────┘ └────┘ ┴ └─┘ └────┘ ┴
pid ┴┴ ┴┴ ┴ ┴ ┴ ┴
st ─────┘└───────┘└──────────┘└────┘└──────────────┘└┘└
722 { cases h with n h, existsi n+1,
id ┴ ┴┴
src └────┘ └───────┘ └──────┘ ┴┴
typ └────┘┴└───────┘ └──────┘┴┴┴
doc └────┘ └───────┘ └──────┘ ┴
txt └────┘ └───────┘ └──────┘ ┴
par └────┘ └───────┘ └──────┘ ┴
pid ┴ └───────┘ ┴ ┴
st ─────────────────────┘└───────────┘└─
723 simp [nth], exact h } },
id └─┘ ┴
src └────┘└─┘┴ └────┘ ┴
typ └────┘└─┘┴ └────┘┴┴
doc └────┘└─┘┴ └────┘ ┴
txt └────┘ ┴ └────┘ ┴
par └────┘ ┴ └────┘ ┴
pid ┴┴ ┴ ┴ ┴
st ───────────────┘└────────┘└──┘└
724 { intros s' h, cases h with n h,
id ┴
src └─────────┘ └────┘ └───────┘
typ └─────────┘ └────┘┴└───────┘
doc └─────────┘ └────┘ └───────┘
txt └─────────┘ └────┘ └───────┘
par └─────────┘ └────┘ └───────┘
pid └───┘ ┴ └───────┘
st ──────────────┘└────────────────┘└─
725 existsi n, simp [nth], apply think_mem h }
id ┴ └─┘ └───────┘ ┴
src └──────┘ └────┘└─┘┴ └────┘└───────┘┴ ┴
typ └──────┘┴ └────┘└─┘┴ └────┘└───────┘┴┴┴
doc └──────┘ └────┘└─┘┴ └────┘ ┴ ┴
txt └──────┘ └────┘ ┴ └────┘ ┴ ┴
par └──────┘ └────┘ ┴ └────┘ ┴ ┴
pid ┴ ┴┴ ┴ ┴ ┴ ┴
st ────────────┘└──────────┘└──────────────────┘└─
726 end
st ──┘
727
728 theorem exists_dropn_of_mem {s : wseq α} {a} (h : a ∈ s) :
id └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴
doc └──┘
729 ∃ n s', some (a, s') ∈ destruct (drop s n) :=
id ┴ ┴ └┘┴ └──┘ ┴┴ └┘ ┴ └──────┘ └──┘ ┴ ┴
src ┴ ┴ └──┘ ┴ ┴ └──────┘ └──┘
typ ┴ ┴ └┘┴ └──┘ ┴┴ └┘ ┴ └──────┘ └──┘ ┴ ┴
doc └──────┘ └──┘
730 let ⟨n, h⟩ := exists_nth_of_mem h in ⟨n, begin
id └─┘ ┴ └───────────────┘ ┴
src └───────────────┘
typ └─┘ ┴ └───────────────┘ ┴
st └─────
731 cases (head_terminates_iff _).1 ⟨_, h⟩ with o om,
id └─────────────────┘ ┴
src └────┘ └─────────────────┘└────┘ └─┘ └─────────┘
typ └────┘ └─────────────────┘└────┘ └─┘┴└─────────┘
doc └────┘ └────┘ └─┘ └─────────┘
txt └────┘ └────┘ └─┘ └─────────┘
par └────┘ └────┘ └─┘ └─────────┘
pid ┴ └────┘ └─┘ ┴└────────┘
st ─────────────────────────────────────────────────┘└─
732 have := mem_unique (mem_map _ om) h,
id └────────┘ └─────┘ └┘ ┴
src └──────┘└────────┘┴ └─────┘└─┘ └┘
typ └──────┘└────────┘┴ └─────┘└─┘└┘└┘┴
doc └──────┘ ┴ └─┘ └┘
txt └──────┘ ┴ └─┘ └┘
par └──────┘ ┴ └─┘ └┘
pid └───┘└─┘ ┴ └─┘ └┘
st ────────────────────────────────────┘└─
733 cases o with o; injection this with i,
id ┴ └──┘
src └────┘ └─────┘ └────────┘ └─────┘
typ └────┘┴└─────┘ └────────┘└──┘└─────┘
doc └────┘ └─────┘ └────────┘ └─────┘
txt └────┘ └─────┘ └────────┘ └─────┘
par └────┘ └─────┘ └────────┘ └─────┘
pid ┴ └─────┘ ┴ └─────┘
st ──────────────────────────────────────┘└─
734 cases o with a' s', dsimp at i,
id ┴
src └────┘ └─────────┘ └────────┘
typ └────┘┴└─────────┘ └────────┘
doc └────┘ └─────────┘ └────────┘
txt └────┘ └─────────┘ └────────┘
par └────┘ └─────────┘ └────────┘
pid ┴ └─────────┘ ┴└──┘
st ───────────────────┘└──────────┘└─
735 rw i at om, exact ⟨_, om⟩
id ┴ └┘
src └─┘ └────┘ └────┘ └─┘ └┘
typ └─┘┴└────┘ └────┘ └─┘└┘└┘
doc └─┘ └────┘ └────┘ └─┘ └┘
txt └─┘ └────┘ └────┘ └─┘ └┘
par └─┘ └────┘ └────┘ └─┘ └┘
pid ┴ └────┘ ┴ └─┘ ┴┴
st ───────────┘└──────────────┘
736 end⟩
st └─┘
737
738 theorem lift_rel_dropn_destruct {R : α → β → Prop} {s t} (H : lift_rel R s t) :
id ┴ ┴ └──────┘ ┴ ┴ ┴
src └──────┘
typ ┴ ┴ └──────┘ ┴ ┴ ┴
doc └──────┘
739 ∀ n, computation.lift_rel (lift_rel_o R (lift_rel R))
id ┴ └──────────────────┘ └────────┘ ┴ └──────┘ ┴
src └──────────────────┘ └────────┘ └──────┘
typ ┴ └──────────────────┘ └────────┘ ┴ └──────┘ ┴
doc └──────────────────┘ └──────┘
740 (destruct (drop s n)) (destruct (drop t n))
id └──────┘ └──┘ ┴ ┴ └──────┘ └──┘ ┴ ┴
src └──────┘ └──┘ └──────┘ └──┘
typ └──────┘ └──┘ ┴ ┴ └──────┘ └──┘ ┴ ┴
doc └──────┘ └──┘ └──────┘ └──┘
741 | 0 := lift_rel_destruct H
id └───────────────┘ ┴
src └───────────────┘
typ └───────────────┘ ┴
742 | (n+1) := begin
id ┴
src ┴
typ ┴
st └─────
743 simp [destruct_tail],
id └───────────┘
src └────┘└───────────┘┴
typ └────┘└───────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ─────────────────────┘└─
744 apply lift_rel_bind,
id └───────────┘
src └────┘└───────────┘
typ └────┘└───────────┘
doc └────┘
txt └────┘
par └────┘
pid ┴
st ────────────────────┘└─
745 apply lift_rel_dropn_destruct n,
id └─────────────────────┘ ┴
src └────┘ ┴
typ └────┘└─────────────────────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ────────────────────────────────┘└─
746 exact λ a b o, match a, b, o with
src └────┘ └──────┘ ┴ └┘ └┘ └─────
typ └────┘ └──────┘ ┴ └┘ └┘ └─────
doc └────┘ └──────┘ ┴ └┘ └┘ └─────
txt └────┘ └──────┘ ┴ └┘ └┘ └─────
par └────┘ └──────┘ ┴ └┘ └┘ └─────
pid ┴ └──────┘ ┴ └┘ └┘ └─────
st ────────────────────────────────────
747 | none, none, _ := by simp
src ───┘ └──────┘ └────────────────────┘ ┴└────
typ ───┘ └──────┘ └────────────────────┘ ┴└────
doc ───┘ └──────┘ └────────────────────┘ ┴└────
txt ───┘ └──────┘ └────────────────────┘ ┴└────
par ───┘ └──────┘ └────────────────────┘ ┴└────
pid ───┘ └──────┘ └────────────────────┘ └─────
st ───────────────────────────────────────────┘└─────
748 | some (a, s), some (b, t), ⟨h1, h2⟩ := by simp [tail.aux]; apply lift_rel_destruct h2
id ┴ └──┘ └──────┘ └───────────────┘ └┘
src ─┘└┘ ┴┴ └┘ └─┘└──┘┴ └┘ └─┘ └┘ └───┘ ┴└────┘└──────┘┴└┘└────┘└───────────────┘┴ └
typ ─┘└┘ ┴┴ └┘ └─┘└──┘┴ └┘ └─┘ └┘ └───┘ ┴└────┘└──────┘┴└──────┘└───────────────┘┴└┘└
doc ─┘└┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └───┘ ┴└────┘ ┴└┘└────┘ ┴ └
txt ─┘└┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └───┘ ┴└────┘ ┴└┘└────┘ ┴ └
par ─┘└┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └───┘ ┴└────┘ ┴└──────┘ ┴ └
pid ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └───┘ └─────┘ └───────┘ ┴ └
st ─┘└────────────────────────────────────────┘└────────────────────────────────────────────
749 end
src ─┘└──┘
typ ─────┘
doc ─┘└──┘
txt ─┘└──┘
par ─────┘
pid ────┘┴
st ─┘└──┘
750 end
st └─┘
751
752 theorem exists_of_lift_rel_left {R : α → β → Prop} {s t}
id ┴ ┴
typ ┴ ┴
753 (H : lift_rel R s t) {a} (h : a ∈ s) : ∃ {b}, b ∈ t ∧ R a b :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘
754 let ⟨n, h⟩ := exists_nth_of_mem h,
id └─┘ ┴ ┴ └───────────────┘ ┴
src └───────────────┘
typ └─┘ ┴ ┴ └───────────────┘ ┴
755 ⟨some (._, s'), sd, rfl⟩ := exists_of_mem_map h,
id └──┘ ┴ └┘ └─┘ └───────────────┘
src └──┘ ┴ └─┘ └───────────────┘
typ └──┘ ┴ └┘ └─┘ └───────────────┘
756 ⟨some (b, t'), td, ⟨ab, _⟩⟩ := (lift_rel_dropn_destruct H n).left sd in
id └──┘ ┴┴ └┘ └┘ └─────────────────────┘ ┴ └──┘
src └──┘ ┴ └─────────────────────┘ └──┘
typ └──┘ ┴┴ └┘ └┘ └─────────────────────┘ ┴ └──┘
757 ⟨b, nth_mem (mem_map ((<$>) prod.fst.{v v}) td), ab⟩
id └─────┘ └─────┘ ┴ └──────┘
src └─────┘ └─────┘ ┴ └──────┘
typ └─────┘ └─────┘ ┴ └──────┘
758
759 theorem exists_of_lift_rel_right {R : α → β → Prop} {s t}
id ┴ ┴
typ ┴ ┴
760 (H : lift_rel R s t) {b} (h : b ∈ t) : ∃ {a}, a ∈ s ∧ R a b :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘
761 by rw ←lift_rel.swap at H; exact exists_of_lift_rel_left H h
id └───────────┘ └─────────────────────┘ ┴ ┴
src └──┘└───────────┘└───┘ └────┘└─────────────────────┘┴ ┴ └
typ └──┘└───────────┘└───┘ └────┘└─────────────────────┘┴┴┴┴└
doc └──┘ └───┘ └────┘ ┴ ┴ └
txt └──┘ └───┘ └────┘ ┴ ┴ └
par └──┘ └───┘ └────┘ ┴ ┴ └
pid └┘ └───┘ ┴ ┴ ┴ └
st └──────────────────────────────────────────────────────────
762
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
763 theorem head_terminates_of_mem {s : wseq α} {a} (h : a ∈ s) : terminates (head s) :=
id └──┘ ┴ ┴ ┴ ┴ └────────┘ └──┘ ┴
src └──┘ ┴ └────────┘ └──┘
typ └──┘ ┴ ┴ ┴ ┴ └────────┘ └──┘ ┴
doc └──┘ └────────┘ └──┘
764 let ⟨n, h⟩ := exists_nth_of_mem h in head_terminates_of_nth_terminates ⟨_, h⟩
id └─┘ ┴ └───────────────┘ ┴ └───────────────────────────────┘
src └───────────────┘ └───────────────────────────────┘
typ └─┘ ┴ └───────────────┘ ┴ └───────────────────────────────┘
765
766 theorem of_mem_append {s₁ s₂ : wseq α} {a : α} : a ∈ append s₁ s₂ → a ∈ s₁ ∨ a ∈ s₂ :=
id └──┘ ┴ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴ └────┘ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘ └────┘
767 seq.of_mem_append
id └───────────────┘
src └───────────────┘
typ └───────────────┘
768
769 theorem mem_append_left {s₁ s₂ : wseq α} {a : α} : a ∈ s₁ → a ∈ append s₁ s₂ :=
id └──┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ └┘ └┘
src └──┘ ┴ ┴ └────┘
typ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ └┘ └┘
doc └──┘ └────┘
770 seq.mem_append_left
id └─────────────────┘
src └─────────────────┘
typ └─────────────────┘
771
772 theorem exists_of_mem_map {f} {b : β} : ∀ {s : wseq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b
id ┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─┘
773 | ⟨g, al⟩ h := let ⟨o, om, oe⟩ := seq.exists_of_mem_map h in
id ┴ └─┘ └───────────────────┘
src └───────────────────┘
typ ┴ └─┘ └───────────────────┘
774 by cases o with a; injection oe with h'; exact ⟨a, om, h'⟩
id ┴ └┘ ┴ └┘ └┘
src └────┘ └─────┘ └────────┘ └──────┘ └────┘ └┘ └┘ └─
typ └────┘┴└─────┘ └────────┘└┘└──────┘ └────┘ ┴└┘└┘└┘└┘└─
doc └────┘ └─────┘ └────────┘ └──────┘ └────┘ └┘ └┘ └─
txt └────┘ └─────┘ └────────┘ └──────┘ └────┘ └┘ └┘ └─
par └────┘ └─────┘ └────────┘ └──────┘ └────┘ └┘ └┘ └─
pid ┴ └─────┘ ┴ └──────┘ ┴ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────
775
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
776 @[simp] theorem lift_rel_nil (R : α → β → Prop) : lift_rel R nil nil :=
id ┴ ┴ └──────┘ ┴ └─┘ └─┘
src └──────┘ └─┘ └─┘
typ ┴ ┴ └──────┘ ┴ └─┘ └─┘
doc └──┘ └──────┘ └─┘ └─┘
777 by rw [lift_rel_destruct_iff]; simp
id └───────────────────┘
src └──┘└───────────────────┘┴ └────
typ └──┘└───────────────────┘┴ └────
doc └──┘ ┴ └────
txt └──┘ ┴ └────
par └──┘ ┴ └────
pid └┘ ┴ └
st └────────────────────────┘┴└──────
778
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
779 @[simp] theorem lift_rel_cons (R : α → β → Prop) (a b s t) :
id ┴ ┴
typ ┴ ┴
doc └──┘
780 lift_rel R (cons a s) (cons b t) ↔ R a b ∧ lift_rel R s t :=
id └──────┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴
src └──────┘ └──┘ └──┘ ┴ ┴ └──────┘
typ └──────┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴
doc └──────┘ └──┘ └──┘ └──────┘
781 by rw [lift_rel_destruct_iff]; simp
id └───────────────────┘
src └──┘└───────────────────┘┴ └────
typ └──┘└───────────────────┘┴ └────
doc └──┘ ┴ └────
txt └──┘ ┴ └────
par └──┘ ┴ └────
pid └┘ ┴ └
st └────────────────────────┘┴└──────
782
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
783 @[simp] theorem lift_rel_think_left (R : α → β → Prop) (s t) :
id ┴ ┴
typ ┴ ┴
doc └──┘
784 lift_rel R (think s) t ↔ lift_rel R s t :=
id └──────┘ ┴ └───┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴
src └──────┘ └───┘ ┴ └──────┘
typ └──────┘ ┴ └───┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴
doc └──────┘ └───┘ └──────┘
785 by rw [lift_rel_destruct_iff, lift_rel_destruct_iff]; simp
id └───────────────────┘ └───────────────────┘
src └──┘└───────────────────┘└┘└───────────────────┘┴ └────
typ └──┘└───────────────────┘└┘└───────────────────┘┴ └────
doc └──┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └────
par └──┘ └┘ ┴ └────
pid └┘ └┘ ┴ └
st └────────────────────────┘└─────────────────────┘┴└──────
786
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
787 @[simp] theorem lift_rel_think_right (R : α → β → Prop) (s t) :
id ┴ ┴
typ ┴ ┴
doc └──┘
788 lift_rel R s (think t) ↔ lift_rel R s t :=
id └──────┘ ┴ ┴ └───┘ ┴ ┴ └──────┘ ┴ ┴ ┴
src └──────┘ └───┘ ┴ └──────┘
typ └──────┘ ┴ ┴ └───┘ ┴ ┴ └──────┘ ┴ ┴ ┴
doc └──────┘ └───┘ └──────┘
789 by rw [lift_rel_destruct_iff, lift_rel_destruct_iff]; simp
id └───────────────────┘ └───────────────────┘
src └──┘└───────────────────┘└┘└───────────────────┘┴ └────
typ └──┘└───────────────────┘└┘└───────────────────┘┴ └────
doc └──┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └────
par └──┘ └┘ ┴ └────
pid └┘ └┘ ┴ └
st └────────────────────────┘└─────────────────────┘┴└──────
790
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
791 theorem cons_congr {s t : wseq α} (a : α) (h : s ~ t) : cons a s ~ cons a t :=
id └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴
doc └──┘ ┴ └──┘ ┴ └──┘
792 by unfold equiv; simp; exact h
id ┴
src └──────────┘ └──┘ └────┘ └
typ └──────────┘ └──┘ └────┘┴└
doc └──────────┘ └──┘ └────┘ └
txt └──────────┘ └──┘ └────┘ └
par └──────────┘ └──┘ └────┘ └
pid └────┘ ┴ └
st └────────────────────────────
793
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
794 theorem think_equiv (s : wseq α) : think s ~ s :=
id └──┘ ┴ └───┘ ┴ ┴ ┴
src └──┘ └───┘ ┴
typ └──┘ ┴ └───┘ ┴ ┴ ┴
doc └──┘ └───┘ ┴
795 by unfold equiv; simp; apply equiv.refl
id └────────┘
src └──────────┘ └──┘ └────┘└────────┘└
typ └──────────┘ └──┘ └────┘└────────┘└
doc └──────────┘ └──┘ └────┘ └
txt └──────────┘ └──┘ └────┘ └
par └──────────┘ └──┘ └────┘ └
pid └────┘ ┴ └
st └─────────────────────────────────────
796
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
797 theorem think_congr {s t : wseq α} (a : α) (h : s ~ t) : think s ~ think t :=
id └──┘ ┴ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └───┘ ┴
src └──┘ ┴ └───┘ ┴ └───┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └───┘ ┴
doc └──┘ ┴ └───┘ ┴ └───┘
798 by unfold equiv; simp; exact h
id ┴
src └──────────┘ └──┘ └────┘ └
typ └──────────┘ └──┘ └────┘┴└
doc └──────────┘ └──┘ └────┘ └
txt └──────────┘ └──┘ └────┘ └
par └──────────┘ └──┘ └────┘ └
pid └────┘ ┴ └
st └────────────────────────────
799
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
800 theorem head_congr : ∀ {s t : wseq α}, s ~ t → head s ~ head t :=
id └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ ┴ └──┘ ┴ └──┘
801 suffices ∀ {s t : wseq α}, s ~ t → ∀ {o}, o ∈ head s → o ∈ head t, from
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴
doc └──┘ ┴ └──┘ └──┘
802 λ s t h o, ⟨this h, this h.symm⟩,
id ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴└───┘
src └───┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴└───┘
803 begin
st └─────
804 intros s t h o ho,
src └───────────────┘
typ └───────────────┘
doc └───────────────┘
txt └───────────────┘
par └───────────────┘
pid └─────────┘
st ──────────────────┘└─
805 rcases @computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩,
id └───────────────────────────┘ └──────┘ ┴ └┘
src └─────┘ └───────────────────────────┘└───────┘ └──────┘┴ └┘ └──────────────────┘
typ └─────┘ └───────────────────────────┘└───────┘ └──────┘┴┴└┘└┘└──────────────────┘
doc └─────┘ └───────┘ └──────┘┴ └┘ └──────────────────┘
txt └─────┘ └───────┘ ┴ └┘ └──────────────────┘
par └─────┘ └───────┘ ┴ └┘ └──────────────────┘
pid ┴ └───────┘ ┴ └┘ └──────────────────┘
st ──────────────────────────────────────────────────────────────────────────────────┘└─
806 rw ←dse,
id └─┘
src └──┘
typ └──┘└─┘
doc └──┘
txt └──┘
par └──┘
pid └┘
st ────────┘└─
807 cases destruct_congr h with l r,
id └────────────┘ ┴
src └────┘└────────────┘┴ └───────┘
typ └────┘└────────────┘┴┴└───────┘
doc └────┘ ┴ └───────┘
txt └────┘ ┴ └───────┘
par └────┘ ┴ └───────┘
pid ┴ ┴ └───────┘
st ────────────────────────────────┘└─
808 rcases l dsm with ⟨dt, dtm, dst⟩,
id ┴ └─┘
src └─────┘ ┴ └──────────────────┘
typ └─────┘┴┴└─┘└──────────────────┘
doc └─────┘ ┴ └──────────────────┘
txt └─────┘ ┴ └──────────────────┘
par └─────┘ ┴ └──────────────────┘
pid ┴ ┴ └──────────────────┘
st ─────────────────────────────────┘└─
809 cases ds with a; cases dt with b,
id └┘ └┘
src └────┘ └─────┘ └────┘ └─────┘
typ └────┘└┘└─────┘ └────┘└┘└─────┘
doc └────┘ └─────┘ └────┘ └─────┘
txt └────┘ └─────┘ └────┘ └─────┘
par └────┘ └─────┘ └────┘ └─────┘
pid ┴ └─────┘ ┴ └─────┘
st ─────────────────────────────────┘└─
810 { apply mem_map _ dtm },
id └─────┘ └─┘
src └────┘└─────┘└─┘ ┴
typ └────┘└─────┘└─┘└─┘┴
doc └────┘ └─┘ ┴
txt └────┘ └─┘ ┴
par └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ───┘└──────────────────┘└┘└
811 { cases b, cases dst },
id ┴ └─┘
src └────┘ └────┘ ┴
typ └────┘┴ └────┘└─┘┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ───┘└─────┘└──────────┘└┘└
812 { cases a, cases dst },
id ┴ └─┘
src └────┘ └────┘ ┴
typ └────┘┴ └────┘└─┘┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ───┘└─────┘└──────────┘└┘└
813 { cases a with a s', cases b with b t', rw dst.left,
id ┴ ┴
src └────┘ └────────┘ └────┘ └────────┘ └─┘
typ └────┘┴└────────┘ └────┘┴└────────┘ └─┘└──────┘
doc └────┘ └────────┘ └────┘ └────────┘ └─┘
txt └────┘ └────────┘ └────┘ └────────┘ └─┘
par └────┘ └────────┘ └────┘ └────────┘ └─┘
pid ┴ └────────┘ ┴ └────────┘ ┴
st ────────────────────┘└─────────────────┘└───────────┘└─
814 exact @mem_map _ _ (@functor.map _ _ (α × wseq α) _ prod.fst)
id └─────┘ └─────────┘ ┴ └──┘ ┴ └──────┘
src └────┘ └─────┘└───┘ └─────────┘└───┘ ┴┴┴└──┘┴ └──┘└──────┘└─
typ └────┘ └─────┘└───┘ └─────────┘└───┘ ┴┴┴└──┘┴┴└──┘└──────┘└─
doc └────┘ └───┘ └───┘ ┴ ┴└──┘┴ └──┘ └─
txt └────┘ └───┘ └───┘ ┴ ┴ ┴ └──┘ └─
par └────┘ └───┘ └───┘ ┴ ┴ ┴ └──┘ └─
pid ┴ └───┘ └───┘ ┴ ┴ ┴ └──┘ └─
st ──────────────────────────────────────────────────────────────────
815 _ (destruct t) dtm }
id └──────┘ ┴ └─┘
src ───────┘ └──────┘┴ └┘ ┴
typ ───────┘ └──────┘┴┴└┘└─┘┴
doc ───────┘ └──────┘┴ └┘ ┴
txt ───────┘ ┴ └┘ ┴
par ───────┘ ┴ └┘ ┴
pid ───────┘ ┴ └┘ ┴
st ────────────────────────┘└─
816 end
st ──┘
817
818 theorem flatten_equiv {c : computation (wseq α)} {s} (h : s ∈ c) : flatten c ~ s :=
id └─────────┘ └──┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
src └─────────┘ └──┘ ┴ └─────┘ ┴
typ └─────────┘ └──┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
doc └─────────┘ └──┘ └─────┘ ┴
819 begin
st └─────
820 apply computation.mem_rec_on h, { simp },
id └────────────────────┘ ┴
src └────┘└────────────────────┘┴ └───┘
typ └────┘└────────────────────┘┴┴ └───┘
doc └────┘ ┴ └───┘
txt └────┘ ┴ └───┘
par └────┘ ┴ └───┘
pid ┴ ┴ ┴
st ───────────────────────────────┘└──┘└───┘└┘└
821 { intro s', apply equiv.trans, simp [think_equiv] }
id └─────────┘ └─────────┘
src └──────┘ └────┘└─────────┘ └────┘└─────────┘└┘
typ └──────┘ └────┘└─────────┘ └────┘└─────────┘└┘
doc └──────┘ └────┘ └────┘ └┘
txt └──────┘ └────┘ └────┘ └┘
par └──────┘ └────┘ └────┘ └┘
pid └─┘ ┴ ┴┴ ┴┴
st ───────────┘└─────────────────┘└───────────────────┘└─
822 end
st ──┘
823
824 theorem lift_rel_flatten {R : α → β → Prop} {c1 : computation (wseq α)} {c2 : computation (wseq β)}
id ┴ ┴ └─────────┘ └──┘ ┴ └─────────┘ └──┘ ┴
src └─────────┘ └──┘ └─────────┘ └──┘
typ ┴ ┴ └─────────┘ └──┘ ┴ └─────────┘ └──┘ ┴
doc └─────────┘ └──┘ └─────────┘ └──┘
825 (h : c1.lift_rel (lift_rel R) c2) : lift_rel R (flatten c1) (flatten c2) :=
id └┘└───────┘ └──────┘ ┴ └┘ └──────┘ ┴ └─────┘ └┘ └─────┘ └┘
src └───────┘ └──────┘ └──────┘ └─────┘ └─────┘
typ └┘└───────┘ └──────┘ ┴ └┘ └──────┘ ┴ └─────┘ └┘ └─────┘ └┘
doc └───────┘ └──────┘ └──────┘ └─────┘ └─────┘
826 let S := λ s t,
id ┴ ┴ ┴
typ ┴ ┴ ┴
827 ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ computation.lift_rel (lift_rel R) c1 c2 in
id ┴ └┘ └┘┴ ┴ ┴ └─────┘ └┘ ┴ ┴ ┴ └─────┘ └┘ ┴ └──────────────────┘ └──────┘ ┴ └┘ └┘
src ┴ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └──────────────────┘ └──────┘
typ ┴ └┘ └┘┴ ┴ ┴ └─────┘ └┘ ┴ ┴ ┴ └─────┘ └┘ ┴ └──────────────────┘ └──────┘ ┴ └┘ └┘
doc └─────┘ └─────┘ └──────────────────┘ └──────┘
828 ⟨S, ⟨c1, c2, rfl, rfl, h⟩, λ s t h,
id ┴ └┘ └┘ └─┘ └─┘ ┴ ┴ ┴ ┴
src └─┘ └─┘
typ ┴ └┘ └┘ └─┘ └─┘ ┴ ┴ ┴ ┴
829 match s, t, h with ._, ._, ⟨c1, c2, rfl, rfl, h⟩ := begin
id ┴ ┴ ┴ └─┘
src └─┘
typ ┴ ┴ ┴ └─┘
st └─────
830 simp, apply lift_rel_bind _ _ h,
id └───────────┘ ┴
src └──┘ └────┘└───────────┘└───┘
typ └──┘ └────┘└───────────┘└───┘┴
doc └──┘ └────┘ └───┘
txt └──┘ └────┘ └───┘
par └──┘ └────┘ └───┘
pid ┴ └───┘
st ───────┘└─────────────────────────┘└─
831 intros a b ab, apply computation.lift_rel.imp _ _ _ (lift_rel_destruct ab),
id └──────────────────────┘ └───────────────┘ └┘
src └───────────┘ └────┘└──────────────────────┘└─────┘ └───────────────┘┴ ┴
typ └───────────┘ └────┘└──────────────────────┘└─────┘ └───────────────┘┴└┘┴
doc └───────────┘ └────┘ └─────┘ ┴ ┴
txt └───────────┘ └────┘ └─────┘ ┴ ┴
par └───────────┘ └────┘ └─────┘ ┴ ┴
pid └─────┘ ┴ └─────┘ ┴ ┴
st ────────────────┘└───────────────────────────────────────────────────────────┘└─
832 intros a b, apply lift_rel_o.imp_right,
id └──────────────────┘
src └────────┘ └────┘└──────────────────┘
typ └────────┘ └────┘└──────────────────┘
doc └────────┘ └────┘
txt └────────┘ └────┘
par └────────┘ └────┘
pid └──┘ ┴
st ─────────────┘└──────────────────────────┘└─
833 intros s t h, refine ⟨return s, return t, _, _, _⟩; simp [h]
id └────┘ ┴ ┴ ┴
src └──────────┘ └─────┘ └────┘┴ └┘ ┴ └────────┘ └────┘ └─
typ └──────────┘ └─────┘ └────┘┴┴└┘ ┴┴└────────┘ └────┘┴└─
doc └──────────┘ └─────┘ └────┘┴ └┘ ┴ └────────┘ └────┘ └─
txt └──────────┘ └─────┘ ┴ └┘ ┴ └────────┘ └────┘ └─
par └──────────┘ └─────┘ ┴ └┘ ┴ └────────┘ └────┘ └─
pid └────┘ ┴ ┴ └┘ ┴ └────────┘ ┴┴ ┴└
st ───────────────┘└────────────────────────────────────────────────
834 end end⟩
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
835
836 theorem flatten_congr {c1 c2 : computation (wseq α)} :
id └─────────┘ └──┘ ┴
src └─────────┘ └──┘
typ └─────────┘ └──┘ ┴
doc └─────────┘ └──┘
837 computation.lift_rel equiv c1 c2 → flatten c1 ~ flatten c2 := lift_rel_flatten
id └──────────────────┘ └───┘ └┘ └┘ └─────┘ └┘ ┴ └─────┘ └┘ └──────────────┘
src └──────────────────┘ └───┘ └─────┘ ┴ └─────┘ └──────────────┘
typ └──────────────────┘ └───┘ └┘ └┘ └─────┘ └┘ ┴ └─────┘ └┘ └──────────────┘
doc └──────────────────┘ └───┘ └─────┘ ┴ └─────┘
838
839 theorem tail_congr {s t : wseq α} (h : s ~ t) : tail s ~ tail t :=
id └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ ┴ └──┘ ┴ └──┘
840 begin
st └─────
841 apply flatten_congr,
id └───────────┘
src └────┘└───────────┘
typ └────┘└───────────┘
doc └────┘
txt └────┘
par └────┘
pid ┴
st ────────────────────┘└─
842 unfold functor.map, rw [←bind_ret, ←bind_ret],
id └──────┘ └──────┘
src └────────────────┘ └───┘└──────┘└─┘└──────┘┴
typ └────────────────┘ └───┘└──────┘└─┘└──────┘┴
doc └────────────────┘ └───┘ └─┘ ┴
txt └────────────────┘ └───┘ └─┘ ┴
par └────────────────┘ └───┘ └─┘ ┴
pid └──────────┘ └─┘ └─┘ ┴
st ───────────────────┘└─────────────┘└─────────┘└──
843 apply lift_rel_bind _ _ (destruct_congr h),
id └───────────┘ └────────────┘ ┴
src └────┘└───────────┘└───┘ └────────────┘┴ ┴
typ └────┘└───────────┘└───┘ └────────────┘┴┴┴
doc └────┘ └───┘ ┴ ┴
txt └────┘ └───┘ ┴ ┴
par └────┘ └───┘ ┴ ┴
pid ┴ └───┘ ┴ ┴
st ───────────────────────────────────────────┘└─
844 intros a b h, simp,
src └──────────┘ └──┘
typ └──────────┘ └──┘
doc └──────────┘ └──┘
txt └──────────┘ └──┘
par └──────────┘ └──┘
pid └────┘
st ─────────────┘└────┘└─
845 cases a with a; cases b with b,
id ┴ ┴
src └────┘ └─────┘ └────┘ └─────┘
typ └────┘┴└─────┘ └────┘┴└─────┘
doc └────┘ └─────┘ └────┘ └─────┘
txt └────┘ └─────┘ └────┘ └─────┘
par └────┘ └─────┘ └────┘ └─────┘
pid ┴ └─────┘ ┴ └─────┘
st ───────────────────────────────┘└─
846 { trivial },
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid ┴
st ───┘└──────┘└┘└
847 { cases h },
id ┴
src └────┘ ┴
typ └────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───┘└──────┘└┘└
848 { cases a, cases h },
id ┴ ┴
src └────┘ └────┘ ┴
typ └────┘┴ └────┘┴┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ───┘└─────┘└────────┘└┘└
849 { cases a with a s', cases b with b t', exact h.right }
id ┴ ┴ └─────┘
src └────┘ └────────┘ └────┘ └────────┘ └────┘└─────┘┴
typ └────┘┴└────────┘ └────┘┴└────────┘ └────┘└─────┘┴
doc └────┘ └────────┘ └────┘ └────────┘ └────┘ ┴
txt └────┘ └────────┘ └────┘ └────────┘ └────┘ ┴
par └────┘ └────────┘ └────┘ └────────┘ └────┘ ┴
pid ┴ └────────┘ ┴ └────────┘ ┴ ┴
st ────────────────────┘└─────────────────┘└──────────────┘└─
850 end
st ──┘
851
852 theorem dropn_congr {s t : wseq α} (h : s ~ t) (n) : drop s n ~ drop t n :=
id └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘ ┴ └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴
doc └──┘ ┴ └──┘ ┴ └──┘
853 by induction n; simp [*, tail_congr]
id ┴ └────────┘
src └────────┘ └───────┘└────────┘└─
typ └────────┘┴ └───────┘└────────┘└─
doc └────────┘ └───────┘ └─
txt └────────┘ └───────┘ └─
par └────────┘ └───────┘ └─
pid ┴ ┴└──┘ ┴└
st └──────────────────────────────────
854
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
855 theorem nth_congr {s t : wseq α} (h : s ~ t) (n) : nth s n ~ nth t n :=
id └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ └─┘ ┴ └─┘
typ └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └──┘ ┴ └─┘ ┴ └─┘
856 head_congr (dropn_congr h _)
id └────────┘ └─────────┘ ┴
src └────────┘ └─────────┘
typ └────────┘ └─────────┘ ┴
857
858 theorem mem_congr {s t : wseq α} (h : s ~ t) (a) : a ∈ s ↔ a ∈ t :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ ┴
859 suffices ∀ {s t : wseq α}, s ~ t → a ∈ s → a ∈ t, from ⟨this h, this h.symm⟩,
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴└───┘
src └──┘ ┴ ┴ ┴ └───┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴└───┘
doc └──┘ ┴
860 λ s t h as, let ⟨n, hn⟩ := exists_nth_of_mem as in
id ┴ ┴ ┴ └┘ └─┘ └┘ └───────────────┘ └┘
src └───────────────┘
typ ┴ ┴ ┴ └┘ └─┘ └┘ └───────────────┘ └┘
861 nth_mem ((nth_congr h _ _).1 hn)
id └─────┘ └───────┘ ┴ ┴
src └─────┘ └───────┘ ┴
typ └─────┘ └───────┘ ┴ ┴
862
863 theorem productive_congr {s t : wseq α} (h : s ~ t) : productive s ↔ productive t :=
id └──┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ └────────┘ ┴
src └──┘ ┴ └────────┘ ┴ └────────┘
typ └──┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ └────────┘ ┴
doc └──┘ ┴ └────────┘ └────────┘
864 forall_congr $ λn, terminates_congr $ nth_congr h _
id └──────────┘ ┴ └──────────────┘ └───────┘ ┴
src └──────────┘ └──────────────┘ └───────┘
typ └──────────┘ ┴ └──────────────┘ └───────┘ ┴
865
866 theorem equiv.ext {s t : wseq α} (h : ∀ n, nth s n ~ nth t n) : s ~ t :=
id └──┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └─┘ ┴ └─┘ ┴
typ └──┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─┘ ┴ └─┘ ┴
867 ⟨λ s t, ∀ n, nth s n ~ nth t n, h, λs t h, begin
id ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
src └─┘ ┴ └─┘
typ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └─┘ ┴ └─┘
st └─────
868 refine lift_rel_def.2 ⟨_, _⟩,
id └──────────┘
src └─────┘└──────────┘└─┘ └───┘
typ └─────┘└──────────┘└─┘ └───┘
doc └─────┘ └─┘ └───┘
txt └─────┘ └─┘ └───┘
par └─────┘ └─┘ └───┘
pid ┴ └─┘ └───┘
st ─────────────────────────────┘└─
869 { rw [←head_terminates_iff, ←head_terminates_iff],
id └─────────────────┘ └─────────────────┘
src └───┘└─────────────────┘└─┘└─────────────────┘┴
typ └───┘└─────────────────┘└─┘└─────────────────┘┴
doc └───┘ └─┘ ┴
txt └───┘ └─┘ ┴
par └───┘ └─┘ ┴
pid └─┘ └─┘ ┴
st ───┘└──────────────────────┘└────────────────────┘└──
870 exact terminates_congr (h 0) },
id └──────────────┘ ┴
src └────┘└──────────────┘┴ └──┘
typ └────┘└──────────────┘┴ ┴└──┘
doc └────┘ ┴ └──┘
txt └────┘ ┴ └──┘
par └────┘ ┴ └──┘
pid ┴ ┴ └─┘┴
st ────────────────────────────────┘└┘└
871 { intros a b ma mb,
src └──────────────┘
typ └──────────────┘
doc └──────────────┘
txt └──────────────┘
par └──────────────┘
pid └────────┘
st ───────────────────┘└─
872 cases a with a; cases b with b,
id ┴ ┴
src └────┘ └─────┘ └────┘ └─────┘
typ └────┘┴└─────┘ └────┘┴└─────┘
doc └────┘ └─────┘ └────┘ └─────┘
txt └────┘ └─────┘ └────┘ └─────┘
par └────┘ └─────┘ └────┘ └─────┘
pid ┴ └─────┘ ┴ └─────┘
st ─────────────────────────────────┘└─
873 { trivial },
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid ┴
st ─────┘└──────┘└┘└
874 { injection mem_unique (mem_map _ ma) ((h 0 _).2 (mem_map _ mb)) },
id └────────┘ └┘ ┴ └─────┘ └┘
src └────────┘└────────┘┴ └─┘ └┘ └──────┘ └─────┘└─┘ └─┘
typ └────────┘└────────┘┴ └─┘└┘└┘ ┴└──────┘ └─────┘└─┘└┘└─┘
doc └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └─┘
txt └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └─┘
par └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └─┘
pid ┴ ┴ └─┘ └┘ └──────┘ └─┘ └┘┴
st ─────┘└─────────────────────────────────────────────────────────────┘└┘└
875 { injection mem_unique (mem_map _ ma) ((h 0 _).2 (mem_map _ mb)) },
id └────────┘ └┘ ┴ └─────┘ └┘
src └────────┘└────────┘┴ └─┘ └┘ └──────┘ └─────┘└─┘ └─┘
typ └────────┘└────────┘┴ └─┘└┘└┘ ┴└──────┘ └─────┘└─┘└┘└─┘
doc └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └─┘
txt └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └─┘
par └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └─┘
pid ┴ ┴ └─┘ └┘ └──────┘ └─┘ └┘┴
st ─────┘└─────────────────────────────────────────────────────────────┘└┘└
876 { cases a with a s', cases b with b t',
id ┴ ┴
src └────┘ └────────┘ └────┘ └────────┘
typ └────┘┴└────────┘ └────┘┴└────────┘
doc └────┘ └────────┘ └────┘ └────────┘
txt └────┘ └────────┘ └────┘ └────────┘
par └────┘ └────────┘ └────┘ └────────┘
pid ┴ └────────┘ ┴ └────────┘
st ──────────────────────┘└─────────────────┘└─
877 injection mem_unique (mem_map _ ma) ((h 0 _).2 (mem_map _ mb)) with ab,
id └────────┘ └┘ ┴ └─────┘ └┘
src └────────┘└────────┘┴ └─┘ └┘ └──────┘ └─────┘└─┘ └────────┘
typ └────────┘└────────┘┴ └─┘└┘└┘ ┴└──────┘ └─────┘└─┘└┘└────────┘
doc └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └────────┘
txt └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └────────┘
par └────────┘ ┴ └─┘ └┘ └──────┘ └─┘ └────────┘
pid ┴ ┴ └─┘ └┘ └──────┘ └─┘ └┘└──────┘
st ───────────────────────────────────────────────────────────────────────────┘└─
878 refine ⟨ab, λ n, _⟩,
id └┘
src └─────┘ └┘ └────┘
typ └─────┘ └┘└┘ └────┘
doc └─────┘ └┘ └────┘
txt └─────┘ └┘ └────┘
par └─────┘ └┘ └────┘
pid ┴ └┘ └────┘
st ────────────────────────┘└─
879 refine (nth_congr (flatten_equiv (mem_map _ ma)) n).symm.trans
id └┘
src └─────┘ ┴ ┴ └─┘ └─┘ └────────────
typ └─────┘ ┴ ┴ └─┘└┘└─┘ └────────────
doc └─────┘ ┴ ┴ └─┘ └─┘ └────────────
txt └─────┘ ┴ ┴ └─┘ └─┘ └────────────
par └─────┘ ┴ ┴ └─┘ └─┘ └────────────
pid ┴ ┴ ┴ └─┘ └─┘ └────────────
st ─────────────────────────────────────────────────────────────────────
880 ((_ : nth (tail s) n ~ nth (tail t) n).trans
id ┴ ┴ └─┘ └──┘ ┴
src ───────┘ └──┘ ┴ ┴ └┘ ┴┴┴└─┘┴ └──┘┴ └┘ └───────
typ ───────┘ └──┘ ┴ ┴┴└┘ ┴┴┴└─┘┴ └──┘┴┴└┘ └───────
doc ───────┘ └──┘ ┴ ┴ └┘ ┴┴┴└─┘┴ └──┘┴ └┘ └───────
txt ───────┘ └──┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───────
par ───────┘ └──┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───────
pid ───────┘ └──┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └───────
st ─────────────────────────────────────────────────────
881 (nth_congr (flatten_equiv (mem_map _ mb)) n)),
id └───────┘ └───────────┘ └─────┘ └┘ ┴
src ───────┘ └───────┘┴ └───────────┘┴ └─────┘└─┘ └─┘ └┘
typ ───────┘ └───────┘┴ └───────────┘┴ └─────┘└─┘└┘└─┘┴└┘
doc ───────┘ ┴ ┴ └─┘ └─┘ └┘
txt ───────┘ ┴ ┴ └─┘ └─┘ └┘
par ───────┘ ┴ ┴ └─┘ └─┘ └┘
pid ───────┘ ┴ ┴ └─┘ └─┘ └┘
st ────────────────────────────────────────────────────┘└─
882 rw [nth_tail, nth_tail], apply h } }
id └──────┘ └──────┘
src └──┘└──────┘└┘└──────┘┴ └────┘ ┴
typ └──┘└──────┘└┘└──────┘┴ └────┘ ┴
doc └──┘ └┘ ┴ └────┘ ┴
txt └──┘ └┘ ┴ └────┘ ┴
par └──┘ └┘ ┴ └────┘ ┴
pid └┘ └┘ ┴ ┴ ┴
st ─────────────────┘└────────┘└─────────┘└───
883 end⟩
st ──┘
884
885 theorem length_eq_map (s : wseq α) : length s = computation.map list.length (to_list s) :=
id └──┘ ┴ └────┘ ┴ ┴ └─────────────┘ └─────────┘ └─────┘ ┴
src └──┘ └────┘ ┴ └─────────────┘ └─────────┘ └─────┘
typ └──┘ ┴ └────┘ ┴ ┴ └─────────────┘ └─────────┘ └─────┘ ┴
doc └──┘ └────┘ └─────────────┘ └─────┘
886 begin
st └─────
887 refine eq_of_bisim
id └─────────┘
src └─────┘└─────────┘└
typ └─────┘└─────────┘└
doc └─────┘ └
txt └─────┘ └
par └─────┘ └
pid ┴ └
st ─────────────────────
888 (λ c1 c2, ∃ (l : list α) (s : wseq α),
id ┴ └──┘ └──┘ ┴ ┴
src ───┘ └──────┘┴└────┘└──┘┴ └─────┘└──┘┴ ┴┴└
typ ───┘ └──────┘┴└────┘└──┘┴ └─────┘└──┘┴┴┴┴└
doc ───┘ └──────┘ └────┘ ┴ └─────┘└──┘┴ ┴ └
txt ───┘ └──────┘ └────┘ ┴ └─────┘ ┴ ┴ └
par ───┘ └──────┘ └────┘ ┴ └─────┘ ┴ ┴ └
pid ───┘ └──────┘ └────┘ ┴ └─────┘ ┴ ┴ └
st ───────────────────────────────────────────
889 c1 = corec length._match_2 (l.length, s) ∧
id ┴ └─────────────┘ └─────┘ ┴
src ─────┘ ┴┴┴ ┴└─────────────┘┴ └─────┘└┘ └┘┴└
typ ─────┘ ┴┴┴ ┴└─────────────┘┴ └─────┘└┘ └┘┴└
doc ─────┘ ┴ ┴ ┴ ┴ └┘ └┘ └
txt ─────┘ ┴ ┴ ┴ ┴ └┘ └┘ └
par ─────┘ ┴ ┴ ┴ ┴ └┘ └┘ └
pid ─────┘ ┴ ┴ ┴ ┴ └┘ └┘ └
st ─────────────────────────────────────────────────
890 c2 = computation.map list.length (corec to_list._match_2 (l, s)))
id └─────────────┘ └─────────┘ └───┘ └──────────────┘
src ─────┘ ┴ ┴└─────────────┘┴└─────────┘┴ └───┘┴└──────────────┘┴ └┘ └───
typ ─────┘ ┴ ┴└─────────────┘┴└─────────┘┴ └───┘┴└──────────────┘┴ └┘ └───
doc ─────┘ ┴ ┴└─────────────┘┴ ┴ └───┘┴ ┴ └┘ └───
txt ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └───
par ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └───
pid ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └───
st ────────────────────────────────────────────────────────────────────────
891 _ ⟨[], s, rfl, rfl⟩,
id ┴ └─┘
src ─────┘ └┘ └┘ └┘└─┘┴
typ ─────┘ └┘┴└┘ └┘└─┘┴
doc ─────┘ └┘ └┘ └┘ ┴
txt ─────┘ └┘ └┘ └┘ ┴
par ─────┘ └┘ └┘ └┘ ┴
pid ─────┘ └┘ └┘ └┘ ┴
st ──────────────────────┘└─
892 intros s1 s2 h, rcases h with ⟨l, s, h⟩, rw [h.left, h.right],
id ┴
src └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
typ └────────────┘ └─────┘┴└─────────────┘ └──┘└────┘└┘└─────┘┴
doc └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
txt └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
par └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
pid └──────┘ ┴ └─────────────┘ └┘ └┘ ┴
st ───────────────┘└───────────────────────┘└──────────┘└───────┘└──
893 apply s.cases_on _ (λ a s, _) (λ s, _);
id └────────┘
src └────┘└────────┘└─┘ └───────┘ └────┘
typ └────┘└────────┘└─┘ └───────┘ └────┘
doc └────┘ └─┘ └───────┘ └────┘
txt └────┘ └─┘ └───────┘ └────┘
par └────┘ └─┘ └───────┘ └────┘
pid ┴ └─┘ └───────┘ └────┘
st ──────────────────────────────────────────
894 repeat {simp [to_list, nil, cons, think, length]},
id └─────┘ └─┘ └──┘ └───┘ └────┘
src └──────┘└────┘└─────┘└┘└─┘└┘└──┘└┘└───┘└┘└────┘┴┴
typ └──────┘└────┘└─────┘└┘└─┘└┘└──┘└┘└───┘└┘└────┘┴┴
doc └──────┘└────┘└─────┘└┘└─┘└┘└──┘└┘└───┘└┘└────┘┴┴
txt └──────┘└────┘ └┘ └┘ └┘ └┘ ┴┴
par └──────┘└────┘ └┘ └┘ └┘ └┘ ┴┴
pid └──────┘ └┘ └┘ └┘ └┘ └┘
st ───────────┘└──────────────────────────────────────┘└┘└
895 { refine ⟨a::l, s, _, _⟩; simp },
id ┴ ┴ ┴
src └─────┘ └┘ └─────┘ └───┘
typ └─────┘ ┴ ┴└┘┴└─────┘ └───┘
doc └─────┘ └┘ └─────┘ └───┘
txt └─────┘ └┘ └─────┘ └───┘
par └─────┘ └┘ └─────┘ └───┘
pid ┴ └┘ └─────┘ ┴
st ───┘└───────────────────────────┘└┘└
896 { refine ⟨l, s, _, _⟩; simp }
id ┴ ┴
src └─────┘ └┘ └─────┘ └───┘
typ └─────┘ ┴└┘┴└─────┘ └───┘
doc └─────┘ └┘ └─────┘ └───┘
txt └─────┘ └┘ └─────┘ └───┘
par └─────┘ └┘ └─────┘ └───┘
pid ┴ └┘ └─────┘ ┴
st ─────────────────────────────┘└─
897 end
st ──┘
898
899 @[simp] theorem of_list_nil : of_list [] = (nil : wseq α) := rfl
id └─────┘ └┘ ┴ └─┘ └──┘ ┴ └─┘
src └─────┘ └┘ ┴ └─┘ └──┘ └─┘
typ └─────┘ └┘ ┴ └─┘ └──┘ ┴ └─┘
doc └──┘ └─────┘ └─┘ └──┘
900
901 @[simp] theorem of_list_cons (a : α) (l) :
id ┴
typ ┴
doc └──┘
902 of_list (a :: l) = cons a (of_list l) :=
id └─────┘ ┴ └┘ ┴ ┴ └──┘ ┴ └─────┘ ┴
src └─────┘ └┘ ┴ └──┘ └─────┘
typ └─────┘ ┴ └┘ ┴ ┴ └──┘ ┴ └─────┘ ┴
doc └─────┘ └──┘ └─────┘
903 show seq.map some (seq.of_list (a :: l)) =
id └─────┘ └──┘ └─────────┘ ┴ └┘ ┴ ┴
src └─────┘ └──┘ └─────────┘ └┘ ┴
typ └─────┘ └──┘ └─────────┘ ┴ └┘ ┴ ┴
doc └─────┘ └─────────┘
904 seq.cons (some a) (seq.map some (seq.of_list l)), by simp
id └──────┘ └──┘ ┴ └─────┘ └──┘ └─────────┘ ┴
src └──────┘ └──┘ └─────┘ └──┘ └─────────┘ └────
typ └──────┘ └──┘ ┴ └─────┘ └──┘ └─────────┘ ┴ └────
doc └──────┘ └─────┘ └─────────┘ └────
txt └────
par └────
pid └
st └─────
905
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
906 @[simp] theorem to_list'_nil (l : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
907 corec to_list._match_2 (l, nil) = return l.reverse :=
id └───┘ └──────────────┘ ┴┴ └─┘ ┴ └────┘ ┴└──────┘
src └───┘ └──────────────┘ ┴ └─┘ ┴ └────┘ └──────┘
typ └───┘ └──────────────┘ ┴┴ └─┘ ┴ └────┘ ┴└──────┘
doc └───┘ └─┘ └────┘
908 destruct_eq_ret rfl
id └─────────────┘ └─┘
src └─────────────┘ └─┘
typ └─────────────┘ └─┘
909
910 @[simp] theorem to_list'_cons (l : list α) (s : wseq α) (a : α) :
id └──┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴
doc └──┘ └──┘
911 corec to_list._match_2 (l, cons a s) =
id └───┘ └──────────────┘ ┴┴ └──┘ ┴ ┴ ┴
src └───┘ └──────────────┘ ┴ └──┘ ┴
typ └───┘ └──────────────┘ ┴┴ └──┘ ┴ ┴ ┴
doc └───┘ └──┘
912 (corec to_list._match_2 (a::l, s)).think :=
id └───┘ └──────────────┘ ┴┴└┘┴ ┴ └───┘
src └───┘ └──────────────┘ ┴ └┘ └───┘
typ └───┘ └──────────────┘ ┴┴└┘┴ ┴ └───┘
doc └───┘ └───┘
913 destruct_eq_think $ by simp [to_list, cons]
id └───────────────┘ └─────┘ └──┘
src └───────────────┘ └────┘└─────┘└┘└──┘└─
typ └───────────────┘ └────┘└─────┘└┘└──┘└─
doc └────┘└─────┘└┘└──┘└─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └─────────────────────
914
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
915 @[simp] theorem to_list'_think (l : list α) (s : wseq α) :
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
916 corec to_list._match_2 (l, think s) =
id └───┘ └──────────────┘ ┴┴ └───┘ ┴ ┴
src └───┘ └──────────────┘ ┴ └───┘ ┴
typ └───┘ └──────────────┘ ┴┴ └───┘ ┴ ┴
doc └───┘ └───┘
917 (corec to_list._match_2 (l, s)).think :=
id └───┘ └──────────────┘ ┴┴ ┴ └───┘
src └───┘ └──────────────┘ ┴ └───┘
typ └───┘ └──────────────┘ ┴┴ ┴ └───┘
doc └───┘ └───┘
918 destruct_eq_think $ by simp [to_list, think]
id └───────────────┘ └─────┘ └───┘
src └───────────────┘ └────┘└─────┘└┘└───┘└─
typ └───────────────┘ └────┘└─────┘└┘└───┘└─
doc └────┘└─────┘└┘└───┘└─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └──────────────────────
919
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
920 theorem to_list'_map (l : list α) (s : wseq α) :
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘
921 corec to_list._match_2 (l, s) =
id └───┘ └──────────────┘ ┴┴ ┴ ┴
src └───┘ └──────────────┘ ┴ ┴
typ └───┘ └──────────────┘ ┴┴ ┴ ┴
doc └───┘
922 ((++) l.reverse) <$> to_list s :=
id ┴ ┴└──────┘ └─┘ └─────┘ ┴
src ┴ └──────┘ └─┘ └─────┘
typ ┴ ┴└──────┘ └─┘ └─────┘ ┴
doc └─────┘
923 begin
st └─────
924 refine eq_of_bisim
id └─────────┘
src └─────┘└─────────┘└
typ └─────┘└─────────┘└
doc └─────┘ └
txt └─────┘ └
par └─────┘ └
pid ┴ └
st ─────────────────────
925 (λ c1 c2, ∃ (l' : list α) (s : wseq α),
id ┴ └──┘ └──┘ ┴ ┴
src ───┘ └──────┘┴└─────┘└──┘┴ └─────┘└──┘┴ ┴┴└
typ ───┘ └──────┘┴└─────┘└──┘┴ └─────┘└──┘┴┴┴┴└
doc ───┘ └──────┘ └─────┘ ┴ └─────┘└──┘┴ ┴ └
txt ───┘ └──────┘ └─────┘ ┴ └─────┘ ┴ ┴ └
par ───┘ └──────┘ └─────┘ ┴ └─────┘ ┴ ┴ └
pid ───┘ └──────┘ └─────┘ ┴ └─────┘ ┴ ┴ └
st ────────────────────────────────────────────
926 c1 = corec to_list._match_2 (l' ++ l, s) ∧
id ┴ └┘ ┴
src ─────┘ ┴┴┴ ┴ ┴ ┴└┘┴ └┘ └┘┴└
typ ─────┘ ┴┴┴ ┴ ┴ ┴└┘┴ └┘ └┘┴└
doc ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └
txt ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └
par ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └
pid ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └
st ─────────────────────────────────────────────────
927 c2 = computation.map ((++) l.reverse) (corec to_list._match_2 (l', s)))
id └─────────────┘ └───────┘ └───┘ └──────────────┘
src ─────┘ ┴ ┴└─────────────┘┴ └──┘└───────┘└┘ └───┘┴└──────────────┘┴ └┘ └───
typ ─────┘ ┴ ┴└─────────────┘┴ └──┘└───────┘└┘ └───┘┴└──────────────┘┴ └┘ └───
doc ─────┘ ┴ ┴└─────────────┘┴ └──┘ └┘ └───┘┴ ┴ └┘ └───
txt ─────┘ ┴ ┴ ┴ └──┘ └┘ ┴ ┴ └┘ └───
par ─────┘ ┴ ┴ ┴ └──┘ └┘ ┴ ┴ └┘ └───
pid ─────┘ ┴ ┴ ┴ └──┘ └┘ ┴ ┴ └┘ └───
st ──────────────────────────────────────────────────────────────────────────────
928 _ ⟨[], s, rfl, rfl⟩,
id ┴ └─┘
src ─────┘ └┘ └┘ └┘└─┘┴
typ ─────┘ └┘┴└┘ └┘└─┘┴
doc ─────┘ └┘ └┘ └┘ ┴
txt ─────┘ └┘ └┘ └┘ ┴
par ─────┘ └┘ └┘ └┘ ┴
pid ─────┘ └┘ └┘ └┘ ┴
st ──────────────────────┘└─
929 intros s1 s2 h, rcases h with ⟨l', s, h⟩, rw [h.left, h.right],
id ┴
src └────────────┘ └─────┘ └──────────────┘ └──┘ └┘ ┴
typ └────────────┘ └─────┘┴└──────────────┘ └──┘└────┘└┘└─────┘┴
doc └────────────┘ └─────┘ └──────────────┘ └──┘ └┘ ┴
txt └────────────┘ └─────┘ └──────────────┘ └──┘ └┘ ┴
par └────────────┘ └─────┘ └──────────────┘ └──┘ └┘ ┴
pid └──────┘ ┴ └──────────────┘ └┘ └┘ ┴
st ───────────────┘└────────────────────────┘└──────────┘└───────┘└──
930 apply s.cases_on _ (λ a s, _) (λ s, _);
id └────────┘
src └────┘└────────┘└─┘ └───────┘ └────┘
typ └────┘└────────┘└─┘ └───────┘ └────┘
doc └────┘ └─┘ └───────┘ └────┘
txt └────┘ └─┘ └───────┘ └────┘
par └────┘ └─┘ └───────┘ └────┘
pid ┴ └─┘ └───────┘ └────┘
st ──────────────────────────────────────────
931 repeat {simp [to_list, nil, cons, think, length]},
id └─────┘ └─┘ └──┘ └───┘ └────┘
src └──────┘└────┘└─────┘└┘└─┘└┘└──┘└┘└───┘└┘└────┘┴┴
typ └──────┘└────┘└─────┘└┘└─┘└┘└──┘└┘└───┘└┘└────┘┴┴
doc └──────┘└────┘└─────┘└┘└─┘└┘└──┘└┘└───┘└┘└────┘┴┴
txt └──────┘└────┘ └┘ └┘ └┘ └┘ ┴┴
par └──────┘└────┘ └┘ └┘ └┘ └┘ ┴┴
pid └──────┘ └┘ └┘ └┘ └┘ └┘
st ───────────┘└──────────────────────────────────────┘└┘└
932 { refine ⟨a::l', s, _, _⟩; simp },
id ┴ └┘ ┴
src └─────┘ └┘ └─────┘ └───┘
typ └─────┘ ┴ └┘└┘┴└─────┘ └───┘
doc └─────┘ └┘ └─────┘ └───┘
txt └─────┘ └┘ └─────┘ └───┘
par └─────┘ └┘ └─────┘ └───┘
pid ┴ └┘ └─────┘ ┴
st ───┘└────────────────────────────┘└┘└
933 { refine ⟨l', s, _, _⟩; simp }
id └┘ ┴
src └─────┘ └┘ └─────┘ └───┘
typ └─────┘ └┘└┘┴└─────┘ └───┘
doc └─────┘ └┘ └─────┘ └───┘
txt └─────┘ └┘ └─────┘ └───┘
par └─────┘ └┘ └─────┘ └───┘
pid ┴ └┘ └─────┘ ┴
st ──────────────────────────────┘└─
934 end
st ──┘
935
936 @[simp] theorem to_list_cons (a : α) (s) :
id ┴
typ ┴
doc └──┘
937 to_list (cons a s) = (list.cons a <$> to_list s).think :=
id └─────┘ └──┘ ┴ ┴ ┴ └───────┘ ┴ └─┘ └─────┘ ┴ └───┘
src └─────┘ └──┘ ┴ └───────┘ └─┘ └─────┘ └───┘
typ └─────┘ └──┘ ┴ ┴ ┴ └───────┘ ┴ └─┘ └─────┘ ┴ └───┘
doc └─────┘ └──┘ └─────┘ └───┘
938 destruct_eq_think $ by unfold to_list; simp; rw to_list'_map; simp; refl
id └───────────────┘ └──────────┘
src └───────────────┘ └────────────┘ └──┘ └─┘└──────────┘ └──┘ └────
typ └───────────────┘ └────────────┘ └──┘ └─┘└──────────┘ └──┘ └────
doc └────────────┘ └──┘ └─┘ └──┘ └────
txt └────────────┘ └──┘ └─┘ └──┘ └────
par └────────────┘ └──┘ └─┘ └──┘ └────
pid └──────┘ ┴ └
st └────────────────────────┘└──────────┘└────────────
939
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
940 @[simp] theorem to_list_nil : to_list (nil : wseq α) = return [] :=
id └─────┘ └─┘ └──┘ ┴ ┴ └────┘ └┘
src └─────┘ └─┘ └──┘ ┴ └────┘ └┘
typ └─────┘ └─┘ └──┘ ┴ ┴ └────┘ └┘
doc └──┘ └─────┘ └─┘ └──┘ └────┘
941 destruct_eq_ret rfl
id └─────────────┘ └─┘
src └─────────────┘ └─┘
typ └─────────────┘ └─┘
942
943 theorem to_list_of_list (l : list α) : l ∈ to_list (of_list l) :=
id └──┘ ┴ ┴ ┴ └─────┘ └─────┘ ┴
src └──┘ ┴ └─────┘ └─────┘
typ └──┘ ┴ ┴ ┴ └─────┘ └─────┘ ┴
doc └─────┘ └─────┘
944 by induction l with a l IH; simp [ret_mem]; exact think_mem (mem_map _ IH)
id ┴ └─────┘ └───────┘ └─────┘ └┘
src └────────┘ └──────────┘ └────┘└─────┘┴ └────┘└───────┘┴ └─────┘└─┘ └─
typ └────────┘┴└──────────┘ └────┘└─────┘┴ └────┘└───────┘┴ └─────┘└─┘└┘└─
doc └────────┘ └──────────┘ └────┘ ┴ └────┘ ┴ └─┘ └─
txt └────────┘ └──────────┘ └────┘ ┴ └────┘ ┴ └─┘ └─
par └────────┘ └──────────┘ └────┘ ┴ └────┘ ┴ └─┘ └─
pid ┴ ┴└─────────┘ ┴┴ ┴ ┴ ┴ └─┘ ┴└
st └────────────────────────────────────────────────────────────────────────
945
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
946 @[simp] theorem destruct_of_seq (s : seq α) :
id └─┘ ┴
src └─┘
typ └─┘ ┴
doc └──┘ └─┘
947 destruct (of_seq s) = return (s.head.map $ λ a, (a, of_seq s.tail)) :=
id └──────┘ └────┘ ┴ ┴ └────┘ ┴└───┘└──┘ ┴ ┴┴ └────┘ ┴└───┘
src └──────┘ └────┘ ┴ └────┘ └───┘└──┘ ┴ └────┘ └───┘
typ └──────┘ └────┘ ┴ ┴ └────┘ ┴└───┘└──┘ ┴ ┴┴ └────┘ ┴└───┘
doc └──────┘ └────┘ └────┘ └───┘ └────┘ └───┘
948 destruct_eq_ret $ begin
id └─────────────┘
src └─────────────┘
typ └─────────────┘
st └─────
949 simp [of_seq, head, destruct, seq.destruct, seq.head],
id └────┘ └──┘ └──────┘ └──────────┘ └──────┘
src └────┘└────┘└┘└──┘└┘└──────┘└┘└──────────┘└┘└──────┘┴
typ └────┘└────┘└┘└──┘└┘└──────┘└┘└──────────┘└┘└──────┘┴
doc └────┘└────┘└┘└──┘└┘└──────┘└┘└──────────┘└┘└──────┘┴
txt └────┘ └┘ └┘ └┘ └┘ ┴
par └────┘ └┘ └┘ └┘ └┘ ┴
pid ┴┴ └┘ └┘ └┘ └┘ ┴
st ──────────────────────────────────────────────────────┘└─
950 rw [show seq.nth (some <$> s) 0 = some <$> seq.nth s 0, by apply seq.map_nth],
id └─┘ ┴ └──┘ └─────┘ ┴ └─────────┘
src └──┘ ┴ ┴ ┴└─┘┴ └──┘┴┴└──┘┴ ┴└─────┘┴ └─────┘└────┘└─────────┘┴
typ └──┘ ┴ ┴ ┴└─┘┴ └──┘┴┴└──┘┴ ┴└─────┘┴┴└─────┘└────┘└─────────┘┴
doc └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴└─────┘┴ └─────┘└────┘ ┴
txt └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─────┘└────┘ ┴
par └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─────┘└────┘ ┴
pid └┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └───────────┘ ┴
st ───────────────────────────────────────────────────────────┘└────────────────┘└──
951 cases seq.nth s 0 with a, { refl },
id └─────┘ ┴
src └────┘└─────┘┴ └───────┘ └───┘
typ └────┘└─────┘┴┴└───────┘ └───┘
doc └────┘└─────┘┴ └───────┘ └───┘
txt └────┘ ┴ └───────┘ └───┘
par └────┘ ┴ └───────┘ └───┘
pid ┴ ┴ ┴└──────┘ ┴
st ─────────────────────────┘└──┘└───┘└┘└
952 unfold functor.map,
src └────────────────┘
typ └────────────────┘
doc └────────────────┘
txt └────────────────┘
par └────────────────┘
pid └──────────┘
st ───────────────────┘└─
953 simp [destruct]
id └──────┘
src └────┘└──────┘└┘
typ └────┘└──────┘└┘
doc └────┘└──────┘└┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st ─────────────────┘
954 end
st └─┘
955
956 @[simp] theorem head_of_seq (s : seq α) : head (of_seq s) = return s.head :=
id └─┘ ┴ └──┘ └────┘ ┴ ┴ └────┘ ┴└───┘
src └─┘ └──┘ └────┘ ┴ └────┘ └───┘
typ └─┘ ┴ └──┘ └────┘ ┴ ┴ └────┘ ┴└───┘
doc └──┘ └─┘ └──┘ └────┘ └────┘ └───┘
957 by simp [head]; cases seq.head s; refl
id └──┘ └──────┘ ┴
src └────┘└──┘┴ └────┘└──────┘┴ └────
typ └────┘└──┘┴ └────┘└──────┘┴┴ └────
doc └────┘└──┘┴ └────┘└──────┘┴ └────
txt └────┘ ┴ └────┘ ┴ └────
par └────┘ ┴ └────┘ ┴ └────
pid ┴┴ ┴ ┴ ┴ └
st └────────────────────────────────────
958
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
959 @[simp] theorem tail_of_seq (s : seq α) : tail (of_seq s) = of_seq s.tail :=
id └─┘ ┴ └──┘ └────┘ ┴ ┴ └────┘ ┴└───┘
src └─┘ └──┘ └────┘ ┴ └────┘ └───┘
typ └─┘ ┴ └──┘ └────┘ ┴ ┴ └────┘ ┴└───┘
doc └──┘ └─┘ └──┘ └────┘ └────┘ └───┘
960 begin
st └─────
961 simp [tail], apply s.cases_on _ (λ x s, _); simp [of_seq], {refl},
id └──┘ └────────┘ └────┘
src └────┘└──┘┴ └────┘└────────┘└─┘ └──────┘ └────┘└────┘┴ └──┘
typ └────┘└──┘┴ └────┘└────────┘└─┘ └──────┘ └────┘└────┘┴ └──┘
doc └────┘└──┘┴ └────┘ └─┘ └──────┘ └────┘└────┘┴ └──┘
txt └────┘ ┴ └────┘ └─┘ └──────┘ └────┘ ┴ └──┘
par └────┘ ┴ └────┘ └─┘ └──────┘ └────┘ ┴ └──┘
pid ┴┴ ┴ ┴ └─┘ └──────┘ ┴┴ ┴
st ────────────┘└────────────────────────────────────────────┘└─────┘└┘└
962 rw [seq.head_cons, seq.tail_cons], refl
id └───────────┘ └───────────┘
src └──┘└───────────┘└┘└───────────┘┴ └───┘
typ └──┘└───────────┘└┘└───────────┘┴ └───┘
doc └──┘ └┘ ┴ └───┘
txt └──┘ └┘ ┴ └───┘
par └──┘ └┘ ┴ └───┘
pid └┘ └┘ ┴ ┴
st ──────────────────┘└─────────────┘└──────┘
963 end
st └─┘
964
965 @[simp] theorem dropn_of_seq (s : seq α) : ∀ n, drop (of_seq s) n = of_seq (s.drop n)
id └─┘ ┴ ┴ └──┘ └────┘ ┴ ┴ ┴ └────┘ ┴└───┘ ┴
src └─┘ └──┘ └────┘ ┴ └────┘ └───┘
typ └─┘ ┴ ┴ └──┘ └────┘ ┴ ┴ ┴ └────┘ ┴└───┘ ┴
doc └──┘ └─┘ └──┘ └────┘ └────┘ └───┘
966 | 0 := rfl
id └─┘
src └─┘
typ └─┘
967 | (n+1) := by dsimp [drop]; rw [dropn_of_seq, tail_of_seq]
id ┴ └──┘ └──────────┘ └─────────┘
src ┴ └─────┘└──┘┴ └──┘ └┘└─────────┘└─
typ ┴ └─────┘└──┘┴ └──┘└──────────┘└┘└─────────┘└─
doc └─────┘└──┘┴ └──┘ └┘ └─
txt └─────┘ ┴ └──┘ └┘ └─
par └─────┘ ┴ └──┘ └┘ └─
pid ┴┴ ┴ └┘ └┘ ┴└
st └─────────────────┘└──────────┘└───────────┘┴└
968
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
969 theorem nth_of_seq (s : seq α) (n) : nth (of_seq s) n = return (seq.nth s n) :=
id └─┘ ┴ └─┘ └────┘ ┴ ┴ ┴ └────┘ └─────┘ ┴ ┴
src └─┘ └─┘ └────┘ ┴ └────┘ └─────┘
typ └─┘ ┴ └─┘ └────┘ ┴ ┴ ┴ └────┘ └─────┘ ┴ ┴
doc └─┘ └─┘ └────┘ └────┘ └─────┘
970 by dsimp [nth]; rw [dropn_of_seq, head_of_seq, seq.head_dropn]
id └─┘ └──────────┘ └─────────┘ └────────────┘
src └─────┘└─┘┴ └──┘└──────────┘└┘└─────────┘└┘└────────────┘└─
typ └─────┘└─┘┴ └──┘└──────────┘└┘└─────────┘└┘└────────────┘└─
doc └─────┘└─┘┴ └──┘ └┘ └┘ └─
txt └─────┘ ┴ └──┘ └┘ └┘ └─
par └─────┘ ┴ └──┘ └┘ └┘ └─
pid ┴┴ ┴ └┘ └┘ └┘ ┴└
st └────────────────┘└──────────┘└───────────┘└──────────────┘┴└
971
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
972 instance productive_of_seq (s : seq α) : productive (of_seq s) :=
id └─┘ ┴ └────────┘ └────┘ ┴
src └─┘ └────────┘ └────┘
typ └─┘ ┴ └────────┘ └────┘ ┴
doc └─┘ └────────┘ └────┘
973 λ n, by rw nth_of_seq; apply_instance
id ┴ └────────┘
src └─┘└────────┘ └──────────────
typ ┴ └─┘└────────┘ └──────────────
doc └─┘ └──────────────
txt └─┘ └──────────────
par └─┘ └──────────────
pid ┴ └
st └──────────────────────────────
974
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
975 theorem to_seq_of_seq (s : seq α) : to_seq (of_seq s) = s :=
id └─┘ ┴ └────┘ └────┘ ┴ ┴ ┴
src └─┘ └────┘ └────┘ ┴
typ └─┘ ┴ └────┘ └────┘ ┴ ┴ ┴
doc └─┘ └────┘ └────┘
976 begin
st └─────
977 apply subtype.eq, funext n,
id └────────┘
src └────┘└────────┘ └──────┘
typ └────┘└────────┘ └──────┘
doc └────┘ └──────┘
txt └────┘ └──────┘
par └────┘ └──────┘
pid ┴ └┘
st ─────────────────┘└────────┘└─
978 dsimp [to_seq], apply get_eq_of_mem,
id └────┘ └───────────┘
src └─────┘└────┘┴ └────┘└───────────┘
typ └─────┘└────┘┴ └────┘└───────────┘
doc └─────┘└────┘┴ └────┘
txt └─────┘ ┴ └────┘
par └─────┘ ┴ └────┘
pid ┴┴ ┴ ┴
st ───────────────┘└───────────────────┘└─
979 rw nth_of_seq, apply ret_mem
id └────────┘ └─────┘
src └─┘└────────┘ └────┘└─────┘┴
typ └─┘└────────┘ └────┘└─────┘┴
doc └─┘ └────┘ ┴
txt └─┘ └────┘ ┴
par └─┘ └────┘ ┴
pid ┴ ┴ ┴
st ──────────────┘└──────────────┘
980 end
st └─┘
981
982 /-- The monadic `return a` is a singleton list containing `a`. -/
983 def ret (a : α) : wseq α := of_list [a]
id ┴ └──┘ ┴ └─────┘ ┴┴┴
src └──┘ └─────┘ ┴ ┴
typ ┴ └──┘ ┴ └─────┘ ┴┴┴
doc └──┘ └─────┘
984
985 @[simp] theorem map_nil (f : α → β) : map f nil = nil := rfl
id ┴ ┴ └─┘ ┴ └─┘ ┴ └─┘ └─┘
src └─┘ └─┘ ┴ └─┘ └─┘
typ ┴ ┴ └─┘ ┴ └─┘ ┴ └─┘ └─┘
doc └──┘ └─┘ └─┘ └─┘
986
987 @[simp] theorem map_cons (f : α → β) (a s) :
id ┴ ┴
typ ┴ ┴
doc └──┘
988 map f (cons a s) = cons (f a) (map f s) := seq.map_cons _ _ _
id └─┘ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ └──────────┘
src └─┘ └──┘ ┴ └──┘ └─┘ └──────────┘
typ └─┘ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ └──────────┘
doc └─┘ └──┘ └──┘ └─┘
989
990 @[simp] theorem map_think (f : α → β) (s) :
id ┴ ┴
typ ┴ ┴
doc └──┘
991 map f (think s) = think (map f s) := seq.map_cons _ _ _
id └─┘ ┴ └───┘ ┴ ┴ └───┘ └─┘ ┴ ┴ └──────────┘
src └─┘ └───┘ ┴ └───┘ └─┘ └──────────┘
typ └─┘ ┴ └───┘ ┴ ┴ └───┘ └─┘ ┴ ┴ └──────────┘
doc └─┘ └───┘ └───┘ └─┘
992
993 @[simp] theorem map_id (s : wseq α) : map id s = s := by simp [map]
id └──┘ ┴ └─┘ └┘ ┴ ┴ ┴ └─┘
src └──┘ └─┘ └┘ ┴ └────┘└─┘└─
typ └──┘ ┴ └─┘ └┘ ┴ ┴ ┴ └────┘└─┘└─
doc └──┘ └──┘ └─┘ └────┘└─┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └───────────
994
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
995 @[simp] theorem map_ret (f : α → β) (a) : map f (ret a) = ret (f a) := by simp [ret]
id ┴ ┴ └─┘ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ └─┘
src └─┘ └─┘ ┴ └─┘ └────┘└─┘└─
typ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ └────┘└─┘└─
doc └──┘ └─┘ └─┘ └─┘ └────┘└─┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └───────────
996
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
997 @[simp] theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) :=
id ┴ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ └────┘ └─┘ ┴ ┴ └─┘ ┴ ┴
src └─┘ └────┘ ┴ └────┘ └─┘ └─┘
typ ┴ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ └────┘ └─┘ ┴ ┴ └─┘ ┴ ┴
doc └──┘ └─┘ └────┘ └────┘ └─┘ └─┘
998 seq.map_append _ _ _
id └────────────┘
src └────────────┘
typ └────────────┘
999
1000 theorem map_comp (f : α → β) (g : β → γ) (s : wseq α) :
id ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1001 map (g ∘ f) s = map g (map f s) :=
id └─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴
src └─┘ ┴ ┴ └─┘ └─┘
typ └─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴
doc └─┘ └─┘ └─┘
1002 begin
st └─────
1003 dsimp [map], rw ←seq.map_comp,
id └─┘ └──────────┘
src └─────┘└─┘┴ └──┘└──────────┘
typ └─────┘└─┘┴ └──┘└──────────┘
doc └─────┘└─┘┴ └──┘
txt └─────┘ ┴ └──┘
par └─────┘ ┴ └──┘
pid ┴┴ ┴ └┘
st ────────────┘└────────────────┘└─
1004 apply congr_fun, apply congr_arg,
id └───────┘ └───────┘
src └────┘└───────┘ └────┘└───────┘
typ └────┘└───────┘ └────┘└───────┘
doc └────┘ └────┘
txt └────┘ └────┘
par └────┘ └────┘
pid ┴ ┴
st ────────────────┘└───────────────┘└─
1005 funext o, cases o; refl
id ┴
src └──────┘ └────┘ └───┘
typ └──────┘ └────┘┴ └───┘
doc └──────┘ └────┘ └───┘
txt └──────┘ └────┘ └───┘
par └──────┘ └────┘ └───┘
pid └┘ ┴ ┴
st ─────────┘└──────────────┘
1006 end
st └─┘
1007
1008 theorem mem_map (f : α → β) {a : α} {s : wseq α} : a ∈ s → f a ∈ map f s :=
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ ┴ └─┘
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └──┘ └─┘
1009 seq.mem_map (option.map f)
id └─────────┘ └────────┘ ┴
src └─────────┘ └────────┘
typ └─────────┘ └────────┘ ┴
1010
1011 -- The converse is not true without additional assumptions
1012 theorem exists_of_mem_join {a : α} : ∀ {S : wseq (wseq α)}, a ∈ join S → ∃ s, s ∈ S ∧ a ∈ s :=
id ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴
typ ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘ └──┘
1013 suffices ∀ ss : wseq α, a ∈ ss → ∀ s S, append s (join S) = ss →
id └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ ┴ └──┘ ┴ ┴ └┘
src └──┘ ┴ └────┘ └──┘ ┴
typ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ ┴ └──┘ ┴ ┴ └┘
doc └──┘ └────┘ └──┘
1014 a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s, from λ S h,
id ┴ ┴ └────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ └────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └────┘ └──┘
1015 (this _ h nil S (by simp) (by simp [h])).resolve_left (not_mem_nil _),
id └──┘ ┴ └─┘ ┴ ┴ └──────────┘ └─────────┘
src └─┘ └──┘ └────┘ ┴ └──────────┘ └─────────┘
typ └──┘ ┴ └─┘ ┴ └──┘ └────┘┴┴ └──────────┘ └─────────┘
doc └─┘ └──┘ └────┘ ┴
txt └──┘ └────┘ ┴
par └──┘ └────┘ ┴
pid ┴┴ ┴
st └───┘ └───────┘
1016 begin
st └─────
1017 intros ss h, apply mem_rec_on h (λ b ss o, _) (λ ss IH, _); intros s S,
id └────────┘ ┴
src └─────────┘ └────┘└────────┘┴ ┴ └──────────┘ └────────┘ └────────┘
typ └─────────┘ └────┘└────────┘┴┴┴ └──────────┘ └────────┘ └────────┘
doc └─────────┘ └────┘ ┴ ┴ └──────────┘ └────────┘ └────────┘
txt └─────────┘ └────┘ ┴ ┴ └──────────┘ └────────┘ └────────┘
par └─────────┘ └────┘ ┴ ┴ └──────────┘ └────────┘ └────────┘
pid └───┘ ┴ ┴ ┴ └──────────┘ └────────┘ └──┘
st ────────────┘└─────────────────────────────────────────────────────────┘└─
1018 { refine s.cases_on (S.cases_on _ (λ s S, _) (λ S, _)) (λ b' s, _) (λ s, _);
id └────────┘ └────────┘
src └─────┘└────────┘┴ └────────┘└─┘ └───────┘ └──────┘ └────────┘ └────┘
typ └─────┘└────────┘┴ └────────┘└─┘ └───────┘ └──────┘ └────────┘ └────┘
doc └─────┘ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
txt └─────┘ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
par └─────┘ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
pid ┴ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
st ───┘└──────────────────────────────────────────────────────────────────────────
1019 intros ej m; simp at ej;
src └─────────┘ └────────┘
typ └─────────┘ └────────┘
doc └─────────┘ └────────┘
txt └─────────┘ └────────┘
par └─────────┘ └────────┘
pid └───┘ ┴└───┘
st ─────────────────────────────
1020 have := congr_arg seq.destruct ej; simp at this;
id └───────┘ └──────────┘ └┘
src └──────┘└───────┘┴└──────────┘┴ └──────────┘
typ └──────┘└───────┘┴└──────────┘┴└┘ └──────────┘
doc └──────┘ ┴└──────────┘┴ └──────────┘
txt └──────┘ ┴ ┴ └──────────┘
par └──────┘ ┴ ┴ └──────────┘
pid └───┘└─┘ ┴ ┴ ┴└─────┘
st ─────────────────────────────────────────────────────
1021 try {cases this}; try {contradiction},
id └──┘
src └───┘└────┘ ┴ └───┘└───────────┘┴
typ └───┘└────┘└──┘┴ └───┘└───────────┘┴
doc └───┘└────┘ ┴ └───┘└───────────┘┴
txt └───┘└────┘ ┴ └───┘└───────────┘┴
par └───┘└────┘ ┴ └───┘└───────────┘┴
pid └──────┘ ┴ └──────────────┘
st ────────┘└────────┘└┘└────┘└───────────┘ └─
1022 substs b' ss,
src └──────────┘
typ └──────────┘
doc └──────────┘
txt └──────────┘
par └──────────┘
pid └────┘
st ───────────────┘└─
1023 simp at m ⊢,
src └─────────┘
typ └─────────┘
doc └─────────┘
txt └─────────┘
par └─────────┘
pid ┴└────┘
st ──────────────┘└─
1024 cases o with e IH, { simp [e] },
id ┴ ┴
src └────┘ └────────┘ └────┘ └┘
typ └────┘┴└────────┘ └────┘┴└┘
doc └────┘ └────────┘ └────┘ └┘
txt └────┘ └────────┘ └────┘ └┘
par └────┘ └────────┘ └────┘ └┘
pid ┴ └────────┘ ┴┴ ┴┴
st ────────────────────┘└──┘└───────┘└┘└
1025 cases m with e m, { simp [e] },
id ┴ ┴
src └────┘ └───────┘ └────┘ └┘
typ └────┘┴└───────┘ └────┘┴└┘
doc └────┘ └───────┘ └────┘ └┘
txt └────┘ └───────┘ └────┘ └┘
par └────┘ └───────┘ └────┘ └┘
pid ┴ └───────┘ ┴┴ ┴┴
st ───────────────────┘└──┘└───────┘└┘└
1026 exact or.imp_left or.inr (IH _ _ rfl m) },
id └─────────┘ └────┘ └┘ └─┘ ┴
src └────┘└─────────┘┴└────┘┴ └───┘└─┘┴ └┘
typ └────┘└─────────┘┴└────┘┴ └┘└───┘└─┘┴┴└┘
doc └────┘ ┴ ┴ └───┘ ┴ └┘
txt └────┘ ┴ ┴ └───┘ ┴ └┘
par └────┘ ┴ ┴ └───┘ ┴ └┘
pid ┴ ┴ ┴ └───┘ ┴ ┴┴
st ───────────────────────────────────────────┘└┘└
1027 { refine s.cases_on (S.cases_on _ (λ s S, _) (λ S, _)) (λ b' s, _) (λ s, _);
id └────────┘ └────────┘
src └─────┘└────────┘┴ └────────┘└─┘ └───────┘ └──────┘ └────────┘ └────┘
typ └─────┘└────────┘┴ └────────┘└─┘ └───────┘ └──────┘ └────────┘ └────┘
doc └─────┘ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
txt └─────┘ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
par └─────┘ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
pid ┴ ┴ └─┘ └───────┘ └──────┘ └────────┘ └────┘
st ───────────────────────────────────────────────────────────────────────────────
1028 intros ej m; simp at ej;
src └─────────┘ └────────┘
typ └─────────┘ └────────┘
doc └─────────┘ └────────┘
txt └─────────┘ └────────┘
par └─────────┘ └────────┘
pid └───┘ ┴└───┘
st ─────────────────────────────
1029 have := congr_arg seq.destruct ej; simp at this;
id └───────┘ └──────────┘ └┘
src └──────┘└───────┘┴└──────────┘┴ └──────────┘
typ └──────┘└───────┘┴└──────────┘┴└┘ └──────────┘
doc └──────┘ ┴└──────────┘┴ └──────────┘
txt └──────┘ ┴ ┴ └──────────┘
par └──────┘ ┴ ┴ └──────────┘
pid └───┘└─┘ ┴ ┴ ┴└─────┘
st ─────────────────────────────────────────────────────
1030 try { try {have := this.1}, contradiction }; subst ss,
id └──┘ └┘
src └─────────┘└──────┘ └┘└─┘└────────────┘┴ └────┘
typ └─────────┘└──────┘└──┘└┘└─┘└────────────┘┴ └────┘└┘
doc └─────────┘└──────┘ └┘└─┘└────────────┘┴ └────┘
txt └─────────┘└──────┘ └┘└─┘└────────────┘┴ └────┘
par └─────────┘└──────┘ └┘└─┘└────────────┘┴ └────┘
pid └──────────────┘ └──────────────────┘ ┴
st ────────┘└──────────────────┘ └──────────────┘└┘└───────┘└─
1031 { apply or.inr, simp at m ⊢,
id └────┘
src └────┘└────┘ └─────────┘
typ └────┘└────┘ └─────────┘
doc └────┘ └─────────┘
txt └────┘ └─────────┘
par └────┘ └─────────┘
pid ┴ ┴└────┘
st ─────┘└──────────┘└───────────┘└─
1032 cases IH s S rfl m with as ex,
id └┘ ┴ ┴ └─┘ ┴
src └────┘ ┴ ┴ ┴└─┘┴ └─────────┘
typ └────┘└┘┴┴┴┴┴└─┘┴┴└─────────┘
doc └────┘ ┴ ┴ ┴ ┴ └─────────┘
txt └────┘ ┴ ┴ ┴ ┴ └─────────┘
par └────┘ ┴ ┴ ┴ ┴ └─────────┘
pid ┴ ┴ ┴ ┴ ┴ └─────────┘
st ──────────────────────────────────┘└─
1033 { exact ⟨s, or.inl rfl, as⟩ },
id ┴ └────┘ └─┘ └┘
src └────┘ └┘└────┘┴└─┘└┘ └┘
typ └────┘ ┴└┘└────┘┴└─┘└┘└┘└┘
doc └────┘ └┘ ┴ └┘ └┘
txt └────┘ └┘ ┴ └┘ └┘
par └────┘ └┘ ┴ └┘ └┘
pid ┴ └┘ ┴ └┘ ┴┴
st ───────┘└────────────────────────┘└┘└
1034 { rcases ex with ⟨s', sS, as⟩,
id └┘
src └─────┘ └────────────────┘
typ └─────┘└┘└────────────────┘
doc └─────┘ └────────────────┘
txt └─────┘ └────────────────┘
par └─────┘ └────────────────┘
pid ┴ └────────────────┘
st ──────────────────────────────────┘└─
1035 exact ⟨s', or.inr sS, as⟩ } },
id └┘ └────┘ └┘ └┘
src └────┘ └┘└────┘┴ └┘ └┘
typ └────┘ └┘└┘└────┘┴└┘└┘└┘└┘
doc └────┘ └┘ ┴ └┘ └┘
txt └────┘ └┘ ┴ └┘ └┘
par └────┘ └┘ ┴ └┘ └┘
pid ┴ └┘ ┴ └┘ ┴┴
st ─────────────────────────────────┘└──┘└
1036 { apply or.inr, simp at m,
id └────┘
src └────┘└────┘ └───────┘
typ └────┘└────┘ └───────┘
doc └────┘ └───────┘
txt └────┘ └───────┘
par └────┘ └───────┘
pid ┴ ┴└──┘
st ─────┘└──────────┘└─────────┘└─
1037 rcases (IH nil S (by simp) (by simp [m])).resolve_left (not_mem_nil _) with ⟨s, sS, as⟩,
id └┘ └─┘ ┴ ┴ └─────────┘
src └─────┘ ┴└─┘┴ ┴ ┴└──┘└┘ ┴└────┘ ┴└──────────────┘ └─────────┘└──────────────────┘
typ └─────┘ └┘┴└─┘┴┴┴ ┴└──┘└┘ ┴└────┘┴┴└──────────────┘ └─────────┘└──────────────────┘
doc └─────┘ ┴└─┘┴ ┴ ┴└──┘└┘ ┴└────┘ ┴└──────────────┘ └──────────────────┘
txt └─────┘ ┴ ┴ ┴ ┴└──┘└┘ ┴└────┘ ┴└──────────────┘ └──────────────────┘
par └─────┘ ┴ ┴ ┴ ┴└──┘└┘ ┴└────┘ ┴└──────────────┘ └──────────────────┘
pid ┴ ┴ ┴ ┴ └─────┘ └─────┘ └───────────────┘ └──────────────────┘
st ─────────────────────────┘└───┘└───┘└───────┘└──────────────────────────────────────────────┘└─
1038 exact ⟨s, by simp [sS], as⟩ },
id ┴ └┘ └┘
src └────┘ └┘ ┴└────┘ ┴└┘ └┘
typ └────┘ ┴└┘ ┴└────┘└┘┴└┘└┘└┘
doc └────┘ └┘ ┴└────┘ ┴└┘ └┘
txt └────┘ └┘ ┴└────┘ ┴└┘ └┘
par └────┘ └┘ ┴└────┘ ┴└┘ └┘
pid ┴ └┘ └─────┘ └─┘ ┴┴
st ─────────────────┘└────────┘└────┘└┘└
1039 { simp at m IH ⊢, apply IH _ _ rfl m } }
id └┘ └─┘ ┴
src └────────────┘ └────┘ └───┘└─┘┴ ┴
typ └────────────┘ └────┘└┘└───┘└─┘┴┴┴
doc └────────────┘ └────┘ └───┘ ┴ ┴
txt └────────────┘ └────┘ └───┘ ┴ ┴
par └────────────┘ └────┘ └───┘ ┴ ┴
pid ┴└───────┘ ┴ └───┘ ┴ ┴
st ───────────────────┘└───────────────────┘└───
1040 end
st ──┘
1041
1042 theorem exists_of_mem_bind {s : wseq α} {f : α → wseq β} {b}
id └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
1043 (h : b ∈ bind s f) : ∃ a ∈ s, b ∈ f a :=
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴
src ┴ └──┘ ┴ ┴ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴
doc └──┘
1044 let ⟨t, tm, bt⟩ := exists_of_mem_join h,
id └─┘ └┘ └────────────────┘ ┴
src └────────────────┘
typ └─┘ └┘ └────────────────┘ ┴
1045 ⟨a, as, e⟩ := exists_of_mem_map tm in ⟨a, as, by rwa e⟩
id ┴ └┘ └───────────────┘ ┴
src └───────────────┘ └──┘
typ ┴ └┘ └───────────────┘ └──┘┴
doc └──┘
txt └──┘
par └──┘
pid ┴
st └────┘
1046
1047 theorem destruct_map (f : α → β) (s : wseq α) :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
doc └──┘
1048 destruct (map f s) = computation.map (option.map (prod.map f (map f))) (destruct s) :=
id └──────┘ └─┘ ┴ ┴ ┴ └─────────────┘ └────────┘ └──────┘ ┴ └─┘ ┴ └──────┘ ┴
src └──────┘ └─┘ ┴ └─────────────┘ └────────┘ └──────┘ └─┘ └──────┘
typ └──────┘ └─┘ ┴ ┴ ┴ └─────────────┘ └────────┘ └──────┘ ┴ └─┘ ┴ └──────┘ ┴
doc └──────┘ └─┘ └─────────────┘ └─┘ └──────┘
1049 begin
st └─────
1050 apply eq_of_bisim (λ c1 c2, ∃ s, c1 = destruct (map f s) ∧
id └─────────┘ ┴ ┴ ┴ ┴
src └────┘└─────────┘┴ └──────┘┴└┘┴┴ ┴┴┴ ┴ ┴ ┴ └┘┴└
typ └────┘└─────────┘┴ └──────┘┴└┘┴┴ ┴┴┴ ┴ ┴ ┴ └┘┴└
doc └────┘ ┴ └──────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
txt └────┘ ┴ └──────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
par └────┘ ┴ └──────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
pid ┴ ┴ └──────┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
st ─────────────────────────────────────────────────────────────
1051 c2 = computation.map (option.map (prod.map f (map f))) (destruct s)),
id └─────────────┘ └────────┘ └──────┘ └─┘ ┴ └──────┘
src ───┘ ┴ ┴└─────────────┘┴ └────────┘┴ └──────┘┴ ┴ └─┘┴ └──┘ └──────┘┴ └┘
typ ───┘ ┴ ┴└─────────────┘┴ └────────┘┴ └──────┘┴ ┴ └─┘┴┴└──┘ └──────┘┴ └┘
doc ───┘ ┴ ┴└─────────────┘┴ ┴ ┴ ┴ └─┘┴ └──┘ └──────┘┴ └┘
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └┘
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └┘
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └┘
st ───────────────────────────────────────────────────────────────────────┘└─
1052 { intros c1 c2 h, cases h with s h, rw [h.left, h.right],
id ┴
src └────────────┘ └────┘ └───────┘ └──┘ └┘ ┴
typ └────────────┘ └────┘┴└───────┘ └──┘└────┘└┘└─────┘┴
doc └────────────┘ └────┘ └───────┘ └──┘ └┘ ┴
txt └────────────┘ └────┘ └───────┘ └──┘ └┘ ┴
par └────────────┘ └────┘ └───────┘ └──┘ └┘ ┴
pid └──────┘ ┴ └───────┘ └┘ └┘ ┴
st ───┘└────────────┘└────────────────┘└──────────┘└───────┘└──
1053 apply s.cases_on _ (λ a s, _) (λ s, _); simp; simp,
id └────────┘
src └────┘└────────┘└─┘ └───────┘ └────┘ └──┘ └──┘
typ └────┘└────────┘└─┘ └───────┘ └────┘ └──┘ └──┘
doc └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
txt └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
par └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
pid ┴ └─┘ └───────┘ └────┘
st ─────────────────────────────────────────────────────┘└─
1054 exact ⟨s, rfl, rfl⟩ },
id ┴ └─┘
src └────┘ └┘ └┘└─┘└┘
typ └────┘ ┴└┘ └┘└─┘└┘
doc └────┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘
pid ┴ └┘ └┘ ┴┴
st ───────────────────────┘└┘└
1055 { exact ⟨s, rfl, rfl⟩ }
id ┴ └─┘
src └────┘ └┘ └┘└─┘└┘
typ └────┘ ┴└┘ └┘└─┘└┘
doc └────┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘
pid ┴ └┘ └┘ ┴┴
st ───────────────────────┘└─
1056 end
st ──┘
1057
1058 theorem lift_rel_map {δ} (R : α → β → Prop) (S : γ → δ → Prop)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
1059 {s1 : wseq α} {s2 : wseq β}
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
1060 {f1 : α → γ} {f2 : β → δ}
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
1061 (h1 : lift_rel R s1 s2) (h2 : ∀ {a b}, R a b → S (f1 a) (f2 b))
id └──────┘ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴
src └──────┘
typ └──────┘ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴
doc └──────┘
1062 : lift_rel S (map f1 s1) (map f2 s2) :=
id └──────┘ ┴ └─┘ └┘ └┘ └─┘ └┘ └┘
src └──────┘ └─┘ └─┘
typ └──────┘ ┴ └─┘ └┘ └┘ └─┘ └┘ └┘
doc └──────┘ └─┘ └─┘
1063 ⟨λ s1 s2, ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ lift_rel R s t,
id └┘ └┘ ┴ ┴ ┴┴ └┘ ┴ └─┘ └┘ ┴ ┴ └┘ ┴ └─┘ └┘ ┴ ┴ └──────┘ ┴ ┴ ┴
src ┴ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴ └──────┘
typ └┘ └┘ ┴ ┴ ┴┴ └┘ ┴ └─┘ └┘ ┴ ┴ └┘ ┴ └─┘ └┘ ┴ ┴ └──────┘ ┴ ┴ ┴
doc └─┘ └─┘ └──────┘
1064 ⟨s1, s2, rfl, rfl, h1⟩,
id └┘ └┘ └─┘ └─┘ └┘
src └─┘ └─┘
typ └┘ └┘ └─┘ └─┘ └┘
1065 λ s1 s2 h, match s1, s2, h with ._, ._, ⟨s, t, rfl, rfl, h⟩ := begin
id └┘ └┘ ┴ └┘ └┘ ┴ └─┘
src └─┘
typ └┘ └┘ ┴ └┘ └┘ ┴ └─┘
st └─────
1066 simp [destruct_map], apply computation.lift_rel_map _ _ (lift_rel_destruct h),
id └──────────┘ └──────────────────────┘ └───────────────┘ ┴
src └────┘└──────────┘┴ └────┘└──────────────────────┘└───┘ └───────────────┘┴ ┴
typ └────┘└──────────┘┴ └────┘└──────────────────────┘└───┘ └───────────────┘┴┴┴
doc └────┘ ┴ └────┘ └───┘ ┴ ┴
txt └────┘ ┴ └────┘ └───┘ ┴ ┴
par └────┘ ┴ └────┘ └───┘ ┴ ┴
pid ┴┴ ┴ ┴ └───┘ ┴ ┴
st ────────────────────┘└────────────────────────────────────────────────────────┘└─
1067 intros o p h,
src └──────────┘
typ └──────────┘
doc └──────────┘
txt └──────────┘
par └──────────┘
pid └────┘
st ─────────────┘└─
1068 cases o with a; cases p with b; simp,
id ┴ ┴
src └────┘ └─────┘ └────┘ └─────┘ └──┘
typ └────┘┴└─────┘ └────┘┴└─────┘ └──┘
doc └────┘ └─────┘ └────┘ └─────┘ └──┘
txt └────┘ └─────┘ └────┘ └─────┘ └──┘
par └────┘ └─────┘ └────┘ └─────┘ └──┘
pid ┴ └─────┘ ┴ └─────┘
st ─────────────────────────────────────┘└─
1069 { cases b; cases h },
id ┴ ┴
src └────┘ └────┘ ┴
typ └────┘┴ └────┘┴┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ───┘└───────────────┘└┘└
1070 { cases a; cases h },
id ┴ ┴
src └────┘ └────┘ ┴
typ └────┘┴ └────┘┴┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ───┘└───────────────┘└┘└
1071 { cases a with a s; cases b with b t, cases h with r h,
id ┴ ┴ ┴
src └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
typ └────┘┴└───────┘ └────┘┴└───────┘ └────┘┴└───────┘
doc └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
txt └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
par └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
pid ┴ └───────┘ ┴ └───────┘ ┴ └───────┘
st ─────────────────────────────────────┘└────────────────┘└─
1072 exact ⟨h2 r, s, rfl, t, rfl, h⟩ }
id └┘ ┴ ┴ ┴ └─┘ ┴
src └────┘ ┴ └┘ └┘ └┘ └┘└─┘└┘ └┘
typ └────┘ └┘┴┴└┘┴└┘ └┘┴└┘└─┘└┘┴└┘
doc └────┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘
txt └────┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘
par └────┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘
pid ┴ ┴ └┘ └┘ └┘ └┘ └┘ ┴┴
st ───────────────────────────────────┘└─
1073 end end⟩
st ──┘
1074
1075 theorem map_congr (f : α → β) {s t : wseq α} (h : s ~ t) : map f s ~ map f t :=
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ └─┘ ┴ └─┘
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └──┘ ┴ └─┘ ┴ └─┘
1076 lift_rel_map _ _ h (λ _ _, congr_arg _)
id └──────────┘ ┴ ┴ ┴ └───────┘
src └──────────┘ └───────┘
typ └──────────┘ ┴ ┴ ┴ └───────┘
1077
1078 @[simp] def destruct_append.aux (t : wseq α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘ └──┘
1079 option (α × wseq α) → computation (option (α × wseq α))
id └────┘ ┴ ┴ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
src └────┘ ┴ └──┘ └─────────┘ └────┘ ┴ └──┘
typ └────┘ ┴ ┴ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
doc └──┘ └─────────┘ └──┘
1080 | none := destruct t
id └──┘ └──────┘ ┴
src └──┘ └──────┘
typ └──┘ └──────┘ ┴
doc └──────┘
1081 | (some (a, s)) := return (some (a, append s t))
id └──┘ ┴┴ ┴ └────┘ └──┘ ┴ └────┘ ┴
src └──┘ ┴ └────┘ └──┘ ┴ └────┘
typ └──┘ ┴┴ ┴ └────┘ └──┘ ┴ └────┘ ┴
doc └────┘ └────┘
1082
1083 theorem destruct_append (s t : wseq α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
1084 destruct (append s t) = (destruct s).bind (destruct_append.aux t) :=
id └──────┘ └────┘ ┴ ┴ ┴ └──────┘ ┴ └──┘ └─────────────────┘ ┴
src └──────┘ └────┘ ┴ └──────┘ └──┘ └─────────────────┘
typ └──────┘ └────┘ ┴ ┴ ┴ └──────┘ ┴ └──┘ └─────────────────┘ ┴
doc └──────┘ └────┘ └──────┘ └──┘
1085 begin
st └─────
1086 apply eq_of_bisim (λ c1 c2, ∃ s t, c1 = destruct (append s t) ∧
id └─────────┘ ┴ ┴ ┴ └────┘ ┴
src └────┘└─────────┘┴ └──────┘┴└──┘┴┴ ┴┴┴ ┴ └────┘┴ ┴ └┘┴└
typ └────┘└─────────┘┴ └──────┘┴└──┘┴┴ ┴┴┴ ┴ └────┘┴ ┴ └┘┴└
doc └────┘ ┴ └──────┘ └──┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └
txt └────┘ ┴ └──────┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
par └────┘ ┴ └──────┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
pid ┴ ┴ └──────┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
st ──────────────────────────────────────────────────────────────────
1087 c2 = (destruct s).bind (destruct_append.aux t)) _ ⟨s, t, rfl, rfl⟩,
id └──────┘ └─────────────────┘ ┴ ┴ └─┘
src ───┘ ┴ ┴ └──────┘┴ └─────┘ └─────────────────┘┴ └───┘ └┘ └┘ └┘└─┘┴
typ ───┘ ┴ ┴ └──────┘┴ └─────┘ └─────────────────┘┴ └───┘ ┴└┘┴└┘ └┘└─┘┴
doc ───┘ ┴ ┴ └──────┘┴ └─────┘ ┴ └───┘ └┘ └┘ └┘ ┴
txt ───┘ ┴ ┴ ┴ └─────┘ ┴ └───┘ └┘ └┘ └┘ ┴
par ───┘ ┴ ┴ ┴ └─────┘ ┴ └───┘ └┘ └┘ └┘ ┴
pid ───┘ ┴ ┴ ┴ └─────┘ ┴ └───┘ └┘ └┘ └┘ ┴
st ─────────────────────────────────────────────────────────────────────┘└─
1088 intros c1 c2 h, rcases h with ⟨s, t, h⟩, rw [h.left, h.right],
id ┴
src └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
typ └────────────┘ └─────┘┴└─────────────┘ └──┘└────┘└┘└─────┘┴
doc └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
txt └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
par └────────────┘ └─────┘ └─────────────┘ └──┘ └┘ ┴
pid └──────┘ ┴ └─────────────┘ └┘ └┘ ┴
st ───────────────┘└───────────────────────┘└──────────┘└───────┘└──
1089 apply s.cases_on _ (λ a s, _) (λ s, _); simp; simp,
id └────────┘
src └────┘└────────┘└─┘ └───────┘ └────┘ └──┘ └──┘
typ └────┘└────────┘└─┘ └───────┘ └────┘ └──┘ └──┘
doc └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
txt └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
par └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
pid ┴ └─┘ └───────┘ └────┘
st ───────────────────────────────────────────────────┘└─
1090 { apply t.cases_on _ (λ b t, _) (λ t, _); simp; simp,
id └────────┘
src └────┘└────────┘└─┘ └───────┘ └────┘ └──┘ └──┘
typ └────┘└────────┘└─┘ └───────┘ └────┘ └──┘ └──┘
doc └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
txt └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
par └────┘ └─┘ └───────┘ └────┘ └──┘ └──┘
pid ┴ └─┘ └───────┘ └────┘
st ───┘└────────────────────────────────────────────────┘└─
1091 { refine ⟨nil, t, _, _⟩; simp } },
id └─┘ ┴
src └─────┘ └─┘└┘ └─────┘ └───┘
typ └─────┘ └─┘└┘┴└─────┘ └───┘
doc └─────┘ └─┘└┘ └─────┘ └───┘
txt └─────┘ └┘ └─────┘ └───┘
par └─────┘ └┘ └─────┘ └───┘
pid ┴ └┘ └─────┘ ┴
st ─────────────────────────────────┘└──┘└
1092 { exact ⟨s, t, rfl, rfl⟩ }
id ┴ ┴ └─┘
src └────┘ └┘ └┘ └┘└─┘└┘
typ └────┘ ┴└┘┴└┘ └┘└─┘└┘
doc └────┘ └┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘ └┘
pid ┴ └┘ └┘ └┘ ┴┴
st ──────────────────────────┘└─
1093 end
st ──┘
1094
1095 @[simp] def destruct_join.aux : option (wseq α × wseq (wseq α)) → computation (option (α × wseq α))
id └────┘ └──┘ ┴ ┴ └──┘ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
src └────┘ └──┘ ┴ └──┘ └──┘ └─────────┘ └────┘ ┴ └──┘
typ └────┘ └──┘ ┴ ┴ └──┘ └──┘ ┴ ┴ └─────────┘ └────┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘ └──┘ └─────────┘ └──┘
1096 | none := return none
id └──┘ └────┘ └──┘
src └──┘ └────┘ └──┘
typ └──┘ └────┘ └──┘
doc └────┘
1097 | (some (s, S)) := (destruct (append s (join S))).think
id └──┘ ┴┴ ┴ └──────┘ └────┘ └──┘ └───┘
src └──┘ ┴ └──────┘ └────┘ └──┘ └───┘
typ └──┘ ┴┴ ┴ └──────┘ └────┘ └──┘ └───┘
doc └──────┘ └────┘ └──┘ └───┘
1098
1099 theorem destruct_join (S : wseq (wseq α)) :
id └──┘ └──┘ ┴
src └──┘ └──┘
typ └──┘ └──┘ ┴
doc └──┘ └──┘
1100 destruct (join S) = (destruct S).bind destruct_join.aux :=
id └──────┘ └──┘ ┴ ┴ └──────┘ ┴ └──┘ └───────────────┘
src └──────┘ └──┘ ┴ └──────┘ └──┘ └───────────────┘
typ └──────┘ └──┘ ┴ ┴ └──────┘ ┴ └──┘ └───────────────┘
doc └──────┘ └──┘ └──────┘ └──┘
1101 begin
st └─────
1102 apply eq_of_bisim (λ c1 c2, c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧
id └─────────┘ ┴ ┴ ┴ ┴ └──┘ ┴
src └────┘└─────────┘┴ └──────┘ ┴┴┴ ┴┴┴┴└┘┴┴ ┴ ┴ ┴ └──┘┴ └┘┴└
typ └────┘└─────────┘┴ └──────┘ ┴┴┴ ┴┴┴┴└┘┴┴ ┴ ┴ ┴ └──┘┴ └┘┴└
doc └────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └──┘┴ └┘ └
txt └────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ └
par └────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ └
pid ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ └
st ──────────────────────────────────────────────────────────────────────
1103 c2 = (destruct S).bind destruct_join.aux) _ (or.inr ⟨S, rfl, rfl⟩),
id └──────┘ └───────────────┘ └────┘ ┴ └─┘
src ───┘ ┴ ┴ └──────┘┴ └─────┘└───────────────┘└──┘ └────┘┴ └┘ └┘└─┘└┘
typ ───┘ ┴ ┴ └──────┘┴ └─────┘└───────────────┘└──┘ └────┘┴ ┴└┘ └┘└─┘└┘
doc ───┘ ┴ ┴ └──────┘┴ └─────┘ └──┘ ┴ └┘ └┘ └┘
txt ───┘ ┴ ┴ ┴ └─────┘ └──┘ ┴ └┘ └┘ └┘
par ───┘ ┴ ┴ ┴ └─────┘ └──┘ ┴ └┘ └┘ └┘
pid ───┘ ┴ ┴ ┴ └─────┘ └──┘ ┴ └┘ └┘ └┘
st ─────────────────────────────────────────────────────────────────────┘└─
1104 intros c1 c2 h, exact match c1, c2, h with
id └┘ └┘ ┴
src └────────────┘ └────┘ ┴ └┘ └┘ └─────
typ └────────────┘ └────┘ ┴└┘└┘└┘└┘┴└─────
doc └────────────┘ └────┘ ┴ └┘ └┘ └─────
txt └────────────┘ └────┘ ┴ └┘ └┘ └─────
par └────────────┘ └────┘ ┴ └┘ └┘ └─────
pid └──────┘ ┴ ┴ └┘ └┘ └─────
st ───────────────┘└────────────────────────────
1105 | _, _, (or.inl $ eq.refl c) := by cases c.destruct; simp
id └────┘ └─────┘ └────────┘
src ─────────┘ └────┘┴ ┴└─────┘┴ └───┘ ┴└────┘└────────┘└┘└────
typ ─────────┘ └────┘┴ ┴└─────┘┴ └───┘ ┴└────┘└────────┘└┘└────
doc ─────────┘ ┴ ┴ ┴ └───┘ ┴└────┘└────────┘└┘└────
txt ─────────┘ ┴ ┴ ┴ └───┘ ┴└────┘ └┘└────
par ─────────┘ ┴ ┴ ┴ └───┘ ┴└────┘ └┘└────
pid ─────────┘ ┴ ┴ ┴ └───┘ └─────┘ └──────
st ───────────────────────────────────┘└───────────────────────
1106 | _, _, or.inr ⟨S, rfl, rfl⟩ := begin
src ─┘└──────┘ ┴ └┘ └┘ └───┘ └
typ ─┘└──────┘ ┴ └┘ └┘ └───┘ └
doc ─┘└──────┘ ┴ └┘ └┘ └───┘ └
txt ─┘└──────┘ ┴ └┘ └┘ └───┘ └
par ─┘└──────┘ ┴ └┘ └┘ └───┘ └
pid ─────────┘ ┴ └┘ └┘ └───┘ └
st ─┘└──────────────────────────────┘└─────
1107 apply S.cases_on _ (λ s S, _) (λ S, _); simp; simp,
id └────────┘
src ───┘└────┘└────────┘└─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ─────────┘└────────┘└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ───┘└────┘ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ───┘└────┘ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ─────────┘ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ─────────┘ └─┘ └───────┘ └───────────────────
st ─────────────────────────────────────────────────────┘└─
1108 { refine or.inr ⟨S, rfl, rfl⟩ }
id └────┘ ┴ └─┘
src ─────┘└─────┘└────┘┴ └┘ └┘└─┘└┘└─
typ ────────────┘└────┘┴ ┴└┘ └┘└─┘└───
doc ─────┘└─────┘ ┴ └┘ └┘ └┘└─
txt ─────┘└─────┘ ┴ └┘ └┘ └┘└─
par ────────────┘ ┴ └┘ └┘ └───
pid ────────────┘ ┴ └┘ └┘ └───
st ─────────────────────────────────┘└─
1109 end end
src ─────────┘
typ ─────────┘
doc ─────────┘
txt ─────────┘
par ─────────┘
pid ────────┘┴
st ────┘└───┘
1110 end
st └─┘
1111
1112 theorem lift_rel_append (R : α → β → Prop) {s1 s2 : wseq α} {t1 t2 : wseq β}
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
1113 (h1 : lift_rel R s1 t1) (h2 : lift_rel R s2 t2) :
id └──────┘ ┴ └┘ └┘ └──────┘ ┴ └┘ └┘
src └──────┘ └──────┘
typ └──────┘ ┴ └┘ └┘ └──────┘ ┴ └┘ └┘
doc └──────┘ └──────┘
1114 lift_rel R (append s1 s2) (append t1 t2) :=
id └──────┘ ┴ └────┘ └┘ └┘ └────┘ └┘ └┘
src └──────┘ └────┘ └────┘
typ └──────┘ ┴ └────┘ └┘ └┘ └────┘ └┘ └┘
doc └──────┘ └────┘ └────┘
1115 ⟨λ s t, lift_rel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ lift_rel R s1 t1,
id ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ └┘ └┘┴ ┴ ┴ └────┘ └┘ └┘ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ └──────┘ ┴ └┘ └┘
src └──────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └────┘ ┴ └──────┘
typ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ └┘ └┘┴ ┴ ┴ └────┘ └┘ └┘ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ └──────┘ ┴ └┘ └┘
doc └──────┘ └────┘ └────┘ └──────┘
1116 or.inr ⟨s1, t1, rfl, rfl, h1⟩,
id └────┘ └┘ └┘ └─┘ └─┘ └┘
src └────┘ └─┘ └─┘
typ └────┘ └┘ └┘ └─┘ └─┘ └┘
1117 λ s t h, match s, t, h with
id ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴
1118 | s, t, or.inl h := begin
id └────┘
src └────┘
typ └────┘
st └─────
1119 apply computation.lift_rel.imp _ _ _ (lift_rel_destruct h),
id └──────────────────────┘ └───────────────┘ ┴
src └────┘└──────────────────────┘└─────┘ └───────────────┘┴ ┴
typ └────┘└──────────────────────┘└─────┘ └───────────────┘┴┴┴
doc └────┘ └─────┘ ┴ ┴
txt └────┘ └─────┘ ┴ ┴
par └────┘ └─────┘ ┴ ┴
pid ┴ └─────┘ ┴ ┴
st ─────────────────────────────────────────────────────────────┘└─
1120 intros a b, apply lift_rel_o.imp_right,
id └──────────────────┘
src └────────┘ └────┘└──────────────────┘
typ └────────┘ └────┘└──────────────────┘
doc └────────┘ └────┘
txt └────────┘ └────┘
par └────────┘ └────┘
pid └──┘ ┴
st ─────────────┘└──────────────────────────┘└─
1121 intros s t, apply or.inl
id └────┘
src └────────┘ └────┘└────┘└
typ └────────┘ └────┘└────┘└
doc └────────┘ └────┘ └
txt └────────┘ └────┘ └
par └────────┘ └────┘ └
pid └──┘ ┴ └
st ─────────────┘└──────────────
1122 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
1123 | ._, ._, or.inr ⟨s1, t1, rfl, rfl, h⟩ := begin
id └────┘ └─┘
src └────┘ └─┘
typ └────┘ └─┘
st └─────
1124 simp [destruct_append],
id └─────────────┘
src └────┘└─────────────┘┴
typ └────┘└─────────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ─────────────────────────┘└─
1125 apply computation.lift_rel_bind _ _ (lift_rel_destruct h),
id └───────────────────────┘ └───────────────┘ ┴
src └────┘└───────────────────────┘└───┘ └───────────────┘┴ ┴
typ └────┘└───────────────────────┘└───┘ └───────────────┘┴┴┴
doc └────┘ └───┘ ┴ ┴
txt └────┘ └───┘ ┴ ┴
par └────┘ └───┘ ┴ ┴
pid ┴ └───┘ ┴ ┴
st ────────────────────────────────────────────────────────────┘└─
1126 intros o p h,
src └──────────┘
typ └──────────┘
doc └──────────┘
txt └──────────┘
par └──────────┘
pid └────┘
st ───────────────┘└─
1127 cases o with a; cases p with b,
id ┴ ┴
src └────┘ └─────┘ └────┘ └─────┘
typ └────┘┴└─────┘ └────┘┴└─────┘
doc └────┘ └─────┘ └────┘ └─────┘
txt └────┘ └─────┘ └────┘ └─────┘
par └────┘ └─────┘ └────┘ └─────┘
pid ┴ └─────┘ ┴ └─────┘
st ─────────────────────────────────┘└─
1128 { simp, apply computation.lift_rel.imp _ _ _ (lift_rel_destruct h2),
id └──────────────────────┘ └───────────────┘ └┘
src └──┘ └────┘└──────────────────────┘└─────┘ └───────────────┘┴ ┴
typ └──┘ └────┘└──────────────────────┘└─────┘ └───────────────┘┴└┘┴
doc └──┘ └────┘ └─────┘ ┴ ┴
txt └──┘ └────┘ └─────┘ ┴ ┴
par └──┘ └────┘ └─────┘ ┴ ┴
pid ┴ └─────┘ ┴ ┴
st ─────┘└──┘└───────────────────────────────────────────────────────────┘└─
1129 intros a b, apply lift_rel_o.imp_right,
id └──────────────────┘
src └────────┘ └────┘└──────────────────┘
typ └────────┘ └────┘└──────────────────┘
doc └────────┘ └────┘
txt └────────┘ └────┘
par └────────┘ └────┘
pid └──┘ ┴
st ───────────────┘└──────────────────────────┘└─
1130 intros s t, apply or.inl },
id └────┘
src └────────┘ └────┘└────┘┴
typ └────────┘ └────┘└────┘┴
doc └────────┘ └────┘ ┴
txt └────────┘ └────┘ ┴
par └────────┘ └────┘ ┴
pid └──┘ ┴ ┴
st ───────────────┘└─────────────┘└┘└
1131 { cases b; cases h },
id ┴ ┴
src └────┘ └────┘ ┴
typ └────┘┴ └────┘┴┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ─────┘└───────────────┘└┘└
1132 { cases a; cases h },
id ┴ ┴
src └────┘ └────┘ ┴
typ └────┘┴ └────┘┴┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ─────┘└───────────────┘└┘└
1133 { cases a with a s; cases b with b t, cases h with r h,
id ┴ ┴ ┴
src └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
typ └────┘┴└───────┘ └────┘┴└───────┘ └────┘┴└───────┘
doc └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
txt └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
par └────┘ └───────┘ └────┘ └───────┘ └────┘ └───────┘
pid ┴ └───────┘ ┴ └───────┘ ┴ └───────┘
st ───────────────────────────────────────┘└────────────────┘└─
1134 simp, exact ⟨r, or.inr ⟨s, rfl, t, rfl, h⟩⟩ }
id ┴ └────┘ ┴ ┴ └─┘ ┴
src └──┘ └────┘ └┘└────┘┴ └┘ └┘ └┘└─┘└┘ └─┘
typ └──┘ └────┘ ┴└┘└────┘┴ ┴└┘ └┘┴└┘└─┘└┘┴└─┘
doc └──┘ └────┘ └┘ ┴ └┘ └┘ └┘ └┘ └─┘
txt └──┘ └────┘ └┘ ┴ └┘ └┘ └┘ └┘ └─┘
par └──┘ └────┘ └┘ ┴ └┘ └┘ └┘ └┘ └─┘
pid ┴ └┘ ┴ └┘ └┘ └┘ └┘ └┘┴
st ─────────┘└──────────────────────────────────────┘└─
1135 end
st ────┘
1136 end⟩
1137
1138 theorem lift_rel_join.lem (R : α → β → Prop) {S T} {U : wseq α → wseq β → Prop}
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
1139 (ST : lift_rel (lift_rel R) S T) (HU : ∀ s1 s2, (∃ s t S T,
id └──────┘ └──────┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴┴
src └──────┘ └──────┘ ┴ ┴
typ └──────┘ └──────┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴┴
doc └──────┘ └──────┘
1140 s1 = append s (join S) ∧ s2 = append t (join T) ∧
id └┘ ┴ └────┘ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ └──┘ ┴ ┴
src ┴ └────┘ └──┘ ┴ ┴ └────┘ └──┘ ┴
typ └┘ ┴ └────┘ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ └──┘ ┴ ┴
doc └────┘ └──┘ └────┘ └──┘
1141 lift_rel R s t ∧ lift_rel (lift_rel R) S T) → U s1 s2) {a} (ma : a ∈ destruct (join S)) :
id └──────┘ ┴ ┴ ┴ ┴ └──────┘ └──────┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ └──────┘ └──┘ ┴
src └──────┘ ┴ └──────┘ └──────┘ ┴ └──────┘ └──┘
typ └──────┘ ┴ ┴ ┴ ┴ └──────┘ └──────┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ └──────┘ └──┘ ┴
doc └──────┘ └──────┘ └──────┘ └──────┘ └──┘
1142 ∃ {b}, b ∈ destruct (join T) ∧ lift_rel_o R U a b :=
id ┴ ┴ ┴ ┴ ┴ └──────┘ └──┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ └──────┘ └──┘ ┴ └────────┘
typ ┴ ┴ ┴ ┴ ┴ └──────┘ └──┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
doc └──────┘ └──┘
1143 begin
st └─────
1144 cases exists_results_of_mem ma with n h, clear ma, revert a S T,
id └───────────────────┘ └┘
src └────┘└───────────────────┘┴ └───────┘ └──────┘ └──────────┘
typ └────┘└───────────────────┘┴└┘└───────┘ └──────┘ └──────────┘
doc └────┘ ┴ └───────┘ └──────┘ └──────────┘
txt └────┘ ┴ └───────┘ └──────┘ └──────────┘
par └────┘ ┴ └───────┘ └──────┘ └──────────┘
pid ┴ ┴ └───────┘ └─┘ └────┘
st ────────────────────────────────────────┘└────────┘└────────────┘└─
1145 apply nat.strong_induction_on n _,
id └─────────────────────┘ ┴
src └────┘└─────────────────────┘┴ └┘
typ └────┘└─────────────────────┘┴┴└┘
doc └────┘ ┴ └┘
txt └────┘ ┴ └┘
par └────┘ ┴ └┘
pid ┴ ┴ └┘
st ──────────────────────────────────┘└─
1146 intros n IH a S T ST ra, simp [destruct_join] at ra, exact
id └───────────┘
src └─────────────────────┘ └────┘└───────────┘└─────┘ └─────
typ └─────────────────────┘ └────┘└───────────┘└─────┘ └─────
doc └─────────────────────┘ └────┘ └─────┘ └─────
txt └─────────────────────┘ └────┘ └─────┘ └─────
par └─────────────────────┘ └────┘ └─────┘ └─────
pid └───────────────┘ ┴┴ ┴┴└───┘ └
st ────────────────────────┘└──────────────────────────┘└───────
1147 let ⟨o, m, k, rs1, rs2, en⟩ := of_results_bind ra,
id └─┘ └─────────────┘ └┘
src ─┘ ┴ └┘ └┘ └┘ └┘ └┘ └───┘└─────────────┘┴ └─
typ ─┘ ┴ └┘ └┘ └┘└─┘└┘ └┘ └───┘└─────────────┘┴└┘└─
doc ─┘ ┴ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
txt ─┘ ┴ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
par ─┘ ┴ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
pid ─┘ ┴ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
st ─────────────────────────────────────────────────────
1148 ⟨p, mT, rop⟩ := computation.exists_of_lift_rel_left (lift_rel_destruct ST) rs1.mem in
id └─────────────────────────────────┘ └───────────────┘ └┘ └──┘
src ─────┘ └┘ └┘ └───┘└─────────────────────────────────┘┴ └───────────────┘┴ └┘ └──┘└───
typ ─────┘ └┘ └┘ └───┘└─────────────────────────────────┘┴ └───────────────┘┴└┘└┘ └──┘└───
doc ─────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
txt ─────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
par ─────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
pid ─────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
st ────────────────────────────────────────────────────────────────────────────────────────────
1149 by exact match o, p, rop, rs1, rs2, mT with
id ┴ ┴ └─┘ └─┘ └─┘ └┘
src ─┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
typ ─┘ └─────┘ ┴┴└┘┴└┘└─┘└┘└─┘└┘└─┘└┘└┘└─────
doc ─┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
txt ─┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
par ─┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
pid ─┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
st ───┘└─────────────────────────────────────────
1150 | none, none, _, rs1, rs2, mT := by simp [destruct_join]; exact
id └───────────┘
src ───┘ └┘ └───┘ └┘ └┘ └──┘ ┴└────┘└───────────┘┴└───────
typ ───┘ └┘ └───┘ └┘ └┘ └──┘ ┴└────┘└───────────┘┴└───────
doc ───┘ └┘ └───┘ └┘ └┘ └──┘ ┴└────┘ ┴└───────
txt ───┘ └┘ └───┘ └┘ └┘ └──┘ ┴└────┘ ┴└───────
par ───┘ └┘ └───┘ └┘ └┘ └──┘ ┴└────┘ ┴└───────
pid ───┘ └┘ └───┘ └┘ └┘ └──┘ └─────┘ └────────
st ────────────────────────────────────┘└────────────────────────────
1151 ⟨none, mem_bind mT (ret_mem _), by rw eq_of_ret_mem rs2.mem; trivial⟩
id └──┘ └──────┘ └┘ └─────┘ └───────────┘ └─────┘
src ───┘ └──┘└┘└──────┘┴ ┴ └─────┘└───┘ ┴└─┘└───────────┘┴└─────┘└┘└─────┘└─
typ ───┘ └──┘└┘└──────┘┴└┘┴ └─────┘└───┘ ┴└─┘└───────────┘┴└─────┘└┘└─────┘└─
doc ───┘ └┘ ┴ ┴ └───┘ ┴└─┘ ┴ └┘└─────┘└─
txt ───┘ └┘ ┴ ┴ └───┘ ┴└─┘ ┴ └┘└─────┘└─
par ───┘ └┘ ┴ ┴ └───┘ ┴└─┘ ┴ └┘└─────┘└─
pid ───┘ └┘ ┴ ┴ └───┘ └──┘ ┴ └──────────
st ─────────────────────────────────────┘└────────────────────────────────┘└─
1152 | some (s, S'), some (t, T'), ⟨st, ST'⟩, rs1, rs2, mT :=
src ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └───
typ ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └───
doc ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └───
txt ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └───
par ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └───
pid ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └───
st ─┘└────────────────────────────────────────────────────────
1153 by simp [destruct_append] at rs2; exact
id └─────────────┘
src ───┘ ┴└────┘└─────────────┘└──────┘└───────
typ ───┘ ┴└────┘└─────────────┘└──────┘└───────
doc ───┘ ┴└────┘ └──────┘└───────
txt ───┘ ┴└────┘ └──────┘└───────
par ───┘ ┴└────┘ └──────┘└───────
pid ───┘ └─────┘ └───────────────
st ─────┘└─────────────────────────────────────
1154 let ⟨k1, rs3, ek⟩ := of_results_think rs2,
id └─┘ └──────────────┘ └─┘
src ───┘ ┴ └┘ └┘ └───┘└──────────────┘┴ └─
typ ───┘ ┴ └┘└─┘└┘ └───┘└──────────────┘┴└─┘└─
doc ───┘ ┴ └┘ └┘ └───┘ ┴ └─
txt ───┘ ┴ └┘ └┘ └───┘ ┴ └─
par ───┘ ┴ └┘ └┘ └───┘ ┴ └─
pid ───┘ ┴ └┘ └┘ └───┘ ┴ └─
st ───────────────────────────────────────────────
1155 ⟨o', m1, n1, rs4, rs5, ek1⟩ := of_results_bind rs3,
id └─┘ └─────────────┘
src ───────┘ └┘ └┘ └┘ └┘ └┘ └───┘└─────────────┘┴ └─
typ ───────┘ └┘ └┘ └┘└─┘└┘ └┘ └───┘└─────────────┘┴ └─
doc ───────┘ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
txt ───────┘ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
par ───────┘ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
pid ───────┘ └┘ └┘ └┘ └┘ └┘ └───┘ ┴ └─
st ────────────────────────────────────────────────────────────
1156 ⟨p', mt, rop'⟩ := computation.exists_of_lift_rel_left (lift_rel_destruct st) rs4.mem in
id └─────────────────────────────────┘ └───────────────┘ └┘
src ───────┘ └┘ └┘ └───┘└─────────────────────────────────┘┴ └───────────────┘┴ └┘ └───
typ ───────┘ └┘ └┘ └───┘└─────────────────────────────────┘┴ └───────────────┘┴└┘└┘ └───
doc ───────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
txt ───────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
par ───────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
pid ───────┘ └┘ └┘ └───┘ ┴ ┴ └┘ └───
st ────────────────────────────────────────────────────────────────────────────────────────────────
1157 by exact match o', p', rop', rs4, rs5, mt with
id └┘ └┘ └──┘ └─┘ └─┘ └┘
src ───┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘└┘└─────
typ ───┘ └─────┘ ┴└┘└┘└┘└┘└──┘└┘└─┘└┘└─┘└┘└┘└─────
doc ───┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
txt ───┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
par ───┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
pid ───┘ └─────┘ ┴ └┘ └┘ └┘ └┘ └┘ └─────
st ─────┘└────────────────────────────────────────────
1158 | none, none, _, rs4, rs5', mt :=
id └──┘
src ─────┘ └┘ └───┘ └┘ └┘ └───
typ ─────┘ └┘ └───┘ └┘└──┘└┘ └───
doc ─────┘ └┘ └───┘ └┘ └┘ └───
txt ─────┘ └┘ └───┘ └┘ └┘ └───
par ─────┘ └┘ └───┘ └┘ └┘ └───
pid ─────┘ └┘ └───┘ └┘ └┘ └───
st ──────────────────────────────────────
1159 have n1 < n, begin
id ┴ ┴
src ─────┘ └──┘┴┴ └───────
typ ─────┘ └──┘┴┴┴└───────
doc ─────┘ └──┘ ┴ └───────
txt ─────┘ └──┘ ┴ └───────
par ─────┘ └──┘ ┴ └───────
pid ─────┘ └──┘ ┴ └───────
st ───────────────────────┘└
1160 rw [en, ek, ek1],
id └┘ └┘ └─┘
src ───────┘└──┘ └┘ └┘ ┴└─
typ ───────┘└──┘└┘└┘└┘└┘└─┘┴└─
doc ───────┘└──┘ └┘ └┘ ┴└─
txt ───────┘└──┘ └┘ └┘ ┴└─
par ───────┘└──┘ └┘ └┘ ┴└─
pid ───────────┘ └┘ └┘ └──
st ─────────────┘└──┘└───┘└──
1161 apply lt_of_lt_of_le _ (nat.le_add_right _ _),
id └────────────┘ └──────────────┘
src ───────┘└────┘└────────────┘└─┘ └──────────────┘└───┘└─
typ ─────────────┘└────────────┘└─┘ └──────────────┘└──────
doc ───────┘└────┘ └─┘ └───┘└─
txt ───────┘└────┘ └─┘ └───┘└─
par ─────────────┘ └─┘ └──────
pid ─────────────┘ └─┘ └──────
st ────────────────────────────────────────────────────┘└─
1162 apply nat.lt_succ_of_le (nat.le_add_right _ _)
id └───────────────┘ └──────────────┘
src ───────┘└────┘└───────────────┘┴ └──────────────┘└─────
typ ─────────────┘└───────────────┘┴ └──────────────┘└─────
doc ───────┘└────┘ ┴ └─────
txt ───────┘└────┘ ┴ └─────
par ─────────────┘ ┴ └─────
pid ─────────────┘ ┴ └─────
st ───────────────────────────────────────────────────────
1163 end,
src ─────┘└────
typ ───────────
doc ─────┘└────
txt ─────┘└────
par ───────────
pid ───────────
st ─────┘└─┘└─
1164 let ⟨ob, mb, rob⟩ := IH _ this ST' rs5' in by refine ⟨ob, _, rob⟩;
id └┘ └─┘ └┘ └─┘
src ─────┘ ┴ └┘ └┘ └───┘ └─┘ ┴ ┴ └──┘ ┴└─────┘ └───┘ ┴└─
typ ─────┘ ┴ └┘ └┘ └───┘└┘└─┘ ┴└─┘┴ └──┘ └──────┘ └┘└───┘└─┘└──
doc ─────┘ ┴ └┘ └┘ └───┘ └─┘ ┴ ┴ └──┘ ┴└─────┘ └───┘ ┴└─
txt ─────┘ ┴ └┘ └┘ └───┘ └─┘ ┴ ┴ └──┘ ┴└─────┘ └───┘ ┴└─
par ─────┘ ┴ └┘ └┘ └───┘ └─┘ ┴ ┴ └──┘ └──────┘ └───┘ └──
pid ─────┘ ┴ └┘ └┘ └───┘ └─┘ ┴ ┴ └──┘ └──────┘ └───┘ └──
st ──────────────────────────────────────────────────┘└─────────────────────
1165 { simp [destruct_join], apply mem_bind mT, simp [destruct_append],
id └───────────┘ └──────┘ └┘ └─────────────┘
src ───────┘└────┘└───────────┘┴└┘└────┘└──────┘┴ └┘└────┘└─────────────┘┴└─
typ ───────┘└────┘└───────────┘┴└──────┘└──────┘┴└┘└┘└────┘└─────────────┘┴└─
doc ───────┘└────┘ ┴└┘└────┘ ┴ └┘└────┘ ┴└─
txt ───────┘└────┘ ┴└┘└────┘ ┴ └┘└────┘ ┴└─
par ───────┘└────┘ ┴└──────┘ ┴ └┘└────┘ ┴└─
pid ─────────────┘ └───────┘ ┴ └──────┘ └──
st ──────┘└───────────────────┘└─────────────────┘└──────────────────────┘└─
1166 apply think_mem, apply mem_bind mt, exact mb }
id └───────┘ └──────┘ └┘ └┘
src ───────┘└────┘└───────┘└┘└────┘└──────┘┴└┘└──────┘ └──
typ ─────────────┘└───────┘└──────┘└──────┘┴└┘└──────┘└┘└──
doc ───────┘└────┘ └┘└────┘ ┴ └──────┘ └──
txt ───────┘└────┘ └┘└────┘ ┴ └──────┘ └──
par ─────────────┘ └──────┘ ┴ └──────┘ └──
pid ─────────────┘ └──────┘ ┴ └──────┘ └──
st ──────────────────────┘└─────────────────┘└─────────┘┴└
1167 | some (a, s'), some (b, t'), ⟨ab, st'⟩, rs4, rs5, mt := begin
src ─────┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └──┘ └
typ ─────┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └──┘ └
doc ─────┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └──┘ └
txt ─────┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └──┘ └
par ─────┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └──┘ └
pid ─────┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └─┘ └┘ └┘ └──┘ └
st ────────────────────────────────────────────────────────────┘└─────
1168 simp at rs5,
src ─────┘└─────────┘└─
typ ─────┘└─────────┘└─
doc ─────┘└─────────┘└─
txt ─────┘└─────────┘└─
par ─────┘└─────────┘└─
pid ───────────────────
st ────────────────┘└─
1169 refine ⟨some (b, append t' (join T')), _, _⟩,
id └──┘ ┴ └────┘ └┘ └──┘ └┘
src ─────┘└─────┘ └──┘┴ └┘└────┘┴ ┴ └──┘┴ └───────┘└─
typ ────────────┘ └──┘┴ ┴└┘└────┘┴└┘┴ └──┘┴└┘└──────────
doc ─────┘└─────┘ ┴ └┘└────┘┴ ┴ └──┘┴ └───────┘└─
txt ─────┘└─────┘ ┴ └┘ ┴ ┴ ┴ └───────┘└─
par ────────────┘ ┴ └┘ ┴ ┴ ┴ └──────────
pid ────────────┘ ┴ └┘ ┴ ┴ ┴ └──────────
st ─────────────────────────────────────────────────┘└─
1170 { simp [destruct_join], apply mem_bind mT, simp [destruct_append],
id └───────────┘ └──────┘ └┘ └─────────────┘
src ───────┘└────┘└───────────┘┴└┘└────┘└──────┘┴ └┘└────┘└─────────────┘┴└─
typ ───────┘└────┘└───────────┘┴└──────┘└──────┘┴└┘└┘└────┘└─────────────┘┴└─
doc ───────┘└────┘ ┴└┘└────┘ ┴ └┘└────┘ ┴└─
txt ───────┘└────┘ ┴└┘└────┘ ┴ └┘└────┘ ┴└─
par ───────┘└────┘ ┴└──────┘ ┴ └┘└────┘ ┴└─
pid ─────────────┘ └───────┘ ┴ └──────┘ └──
st ──────┘└───────────────────┘└─────────────────┘└──────────────────────┘└─
1171 apply think_mem, apply mem_bind mt, apply ret_mem },
id └───────┘ └──────┘ └┘ └─────┘
src ───────┘└────┘└───────┘└┘└────┘└──────┘┴└┘└┘└────┘└─────┘┴└──
typ ─────────────┘└───────┘└──────┘└──────┘┴└┘└──────┘└─────┘└───
doc ───────┘└────┘ └┘└────┘ ┴ └┘└────┘ ┴└──
txt ───────┘└────┘ └┘└────┘ ┴ └┘└────┘ ┴└──
par ─────────────┘ └──────┘ ┴ └──────┘ └───
pid ─────────────┘ └──────┘ ┴ └──────┘ └───
st ──────────────────────┘└─────────────────┘└──────────────┘┴└─
1172 rw eq_of_ret_mem rs5.mem,
id └───────────┘ └─────┘
src ─────┘└─┘└───────────┘┴└─────┘└─
typ ─────┘└─┘└───────────┘┴└─────┘└─
doc ─────┘└─┘ ┴ └─
txt ─────┘└─┘ ┴ └─
par ─────┘└─┘ ┴ └─
pid ────────┘ ┴ └─
st ─────────────────────────────┘└─
1173 exact ⟨ab, HU _ _ ⟨s', t', S', T', rfl, rfl, st', ST'⟩⟩
id └┘ └┘ └┘ └┘ └┘ └┘ └─┘ └─┘ └─┘
src ───────────┘ └┘ └───┘ └┘ └┘ └┘ └┘ └┘└─┘└┘ └┘ └──
typ ───────────┘ └┘└┘└┘└───┘ └┘└┘└┘└┘└┘└┘└┘└┘ └┘└─┘└┘└─┘└┘└─┘└──
doc ───────────┘ └┘ └───┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
txt ───────────┘ └┘ └───┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
par ───────────┘ └┘ └───┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
pid ───────────┘ └┘ └───┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
st ──────────────────────────────────────────────────────────────
1174 end end
src ────────────
typ ────────────
doc ────────────
txt ────────────
par ────────────
pid ────────────
st ───┘└─┘└────
1175 end
src ─────┘
typ ─────┘
doc ─────┘
txt ─────┘
par ─────┘
pid ─────┘
st ─┘└──┘
1176 end
st └─┘
1177
1178 theorem lift_rel_join (R : α → β → Prop) {S : wseq (wseq α)} {T : wseq (wseq β)}
id ┴ ┴ └──┘ └──┘ ┴ └──┘ └──┘ ┴
src └──┘ └──┘ └──┘ └──┘
typ ┴ ┴ └──┘ └──┘ ┴ └──┘ └──┘ ┴
doc └──┘ └──┘ └──┘ └──┘
1179 (h : lift_rel (lift_rel R) S T) : lift_rel R (join S) (join T) :=
id └──────┘ └──────┘ ┴ ┴ ┴ └──────┘ ┴ └──┘ ┴ └──┘ ┴
src └──────┘ └──────┘ └──────┘ └──┘ └──┘
typ └──────┘ └──────┘ ┴ ┴ ┴ └──────┘ ┴ └──┘ ┴ └──┘ ┴
doc └──────┘ └──────┘ └──────┘ └──┘ └──┘
1180 ⟨λ s1 s2, ∃ s t S T,
id └┘ └┘ ┴ ┴ ┴ ┴ ┴┴
src ┴ ┴
typ └┘ └┘ ┴ ┴ ┴ ┴ ┴┴
1181 s1 = append s (join S) ∧ s2 = append t (join T) ∧
id └┘ ┴ └────┘ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ └──┘ ┴ ┴
src ┴ └────┘ └──┘ ┴ ┴ └────┘ └──┘ ┴
typ └┘ ┴ └────┘ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ └──┘ ┴ ┴
doc └────┘ └──┘ └────┘ └──┘
1182 lift_rel R s t ∧ lift_rel (lift_rel R) S T,
id └──────┘ ┴ ┴ ┴ ┴ └──────┘ └──────┘ ┴ ┴ ┴
src └──────┘ ┴ └──────┘ └──────┘
typ └──────┘ ┴ ┴ ┴ ┴ └──────┘ └──────┘ ┴ ┴ ┴
doc └──────┘ └──────┘ └──────┘
1183 ⟨nil, nil, S, T, by simp, by simp, by simp, h⟩,
id └─┘ └─┘ ┴ ┴ ┴
src └─┘ └─┘ └──┘ └──┘ └──┘
typ └─┘ └─┘ ┴ ┴ └──┘ └──┘ └──┘ ┴
doc └─┘ └─┘ └──┘ └──┘ └──┘
txt └──┘ └──┘ └──┘
par └──┘ └──┘ └──┘
st └───┘ └───┘ └───┘
1184 λs1 s2 ⟨s, t, S, T, h1, h2, st, ST⟩, begin
id └┘ └┘ ┴
typ └┘ └┘ ┴
st └─────
1185 clear _fun_match _x,
src └─────────────────┘
typ └─────────────────┘
doc └─────────────────┘
txt └─────────────────┘
par └─────────────────┘
pid └────────────┘
st ────────────────────┘└─
1186 rw [h1, h2], rw [destruct_append, destruct_append],
id └┘ └┘ └─────────────┘ └─────────────┘
src └──┘ └┘ ┴ └──┘└─────────────┘└┘└─────────────┘┴
typ └──┘└┘└┘└┘┴ └──┘└─────────────┘└┘└─────────────┘┴
doc └──┘ └┘ ┴ └──┘ └┘ ┴
txt └──┘ └┘ ┴ └──┘ └┘ ┴
par └──┘ └┘ ┴ └──┘ └┘ ┴
pid └┘ └┘ ┴ └┘ └┘ ┴
st ───────┘└──┘└────────────────────┘└───────────────┘└──
1187 apply computation.lift_rel_bind _ _ (lift_rel_destruct st),
id └───────────────────────┘ └───────────────┘ └┘
src └────┘└───────────────────────┘└───┘ └───────────────┘┴ ┴
typ └────┘└───────────────────────┘└───┘ └───────────────┘┴└┘┴
doc └────┘ └───┘ ┴ ┴
txt └────┘ └───┘ ┴ ┴
par └────┘ └───┘ ┴ ┴
pid ┴ └───┘ ┴ ┴
st ───────────────────────────────────────────────────────────┘└─
1188 exact λ o p h, match o, p, h with
src └────┘ └──────┘ ┴ └┘ └┘ └─────
typ └────┘ └──────┘ ┴ └┘ └┘ └─────
doc └────┘ └──────┘ ┴ └┘ └┘ └─────
txt └────┘ └──────┘ ┴ └┘ └┘ └─────
par └────┘ └──────┘ ┴ └┘ └┘ └─────
pid ┴ └──────┘ ┴ └┘ └┘ └─────
st ────────────────────────────────────
1189 | some (a, s), some (b, t), ⟨h1, h2⟩ :=
id ┴
src ───┘ ┴┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └────
typ ───┘ ┴┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └────
doc ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └────
txt ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └────
par ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └────
pid ───┘ ┴ └┘ └─┘ ┴ └┘ └─┘ └┘ └────
st ──────────────────────────────────────────
1190 by simp; exact ⟨h1, s, t, S, rfl, T, rfl, h2, ST⟩
id └┘ ┴ ┴ ┴ ┴ └─┘ └┘ └┘
src ───┘ ┴└──┘└──────┘ └┘ └┘ └┘ └┘ └┘ └┘└─┘└┘ └┘ └─
typ ───┘ ┴└──┘└──────┘ └┘└┘┴└┘┴└┘┴└┘ └┘┴└┘└─┘└┘└┘└┘└┘└─
doc ───┘ ┴└──┘└──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
txt ───┘ ┴└──┘└──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
par ───┘ ┴└──┘└──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
pid ───┘ └───────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
st ─────┘└───────────────────────────────────────────────
1191 | none, none, _ := begin
src ───┘ └┘ └─────┘ └
typ ───┘ └┘ └─────┘ └
doc ───┘ └┘ └─────┘ └
txt ───┘ └┘ └─────┘ └
par ───┘ └┘ └─────┘ └
pid ───┘ └┘ └─────┘ └
st ─┘└─────────────────┘└─────
1192 dsimp [destruct_append.aux, computation.lift_rel], constructor,
id └─────────────────┘ └──────────────────┘
src ───┘└─────┘└─────────────────┘└┘└──────────────────┘┴└┘└─────────┘└─
typ ───┘└─────┘└─────────────────┘└┘└──────────────────┘┴└┘└─────────┘└─
doc ───┘└─────┘ └┘└──────────────────┘┴└┘└─────────┘└─
txt ───┘└─────┘ └┘ ┴└┘└─────────┘└─
par ───┘└─────┘ └┘ ┴└┘└─────────┘└─
pid ──────────┘ └┘ └───────────────
st ────────────────────────────────────────────────────┘└───────────┘└─
1193 { intro, apply lift_rel_join.lem _ ST (λ _ _, id) },
id └───────────────┘ └┘ └┘
src ─────┘└───┘└┘└────┘└───────────────┘└─┘ ┴ └────┘└┘└┘└──
typ ─────┘└───┘└──────┘└───────────────┘└─┘└┘┴ └────┘└┘└────
doc ─────┘└───┘└┘└────┘ └─┘ ┴ └────┘ └┘└──
txt ─────┘└───┘└┘└────┘ └─┘ ┴ └────┘ └┘└──
par ─────┘└───┘└──────┘ └─┘ ┴ └────┘ └────
pid ──────────────────┘ └─┘ ┴ └────┘ └────
st ────┘└────┘└─────────────────────────────────────────┘┴└─
1194 { intros b mb,
src ─────┘└─────────┘└─
typ ─────┘└─────────┘└─
doc ─────┘└─────────┘└─
txt ─────┘└─────────┘└─
par ─────┘└─────────┘└─
pid ───────────────────
st ────────────────┘└─
1195 rw [←lift_rel_o.swap], apply lift_rel_join.lem (function.swap R),
id └─────────────┘ └───────────────┘ └───────────┘ ┴
src ─────┘└───┘└─────────────┘┴└┘└────┘└───────────────┘┴ └───────────┘┴ ┴└─
typ ─────┘└───┘└─────────────┘┴└──────┘└───────────────┘┴ └───────────┘┴┴└──
doc ─────┘└───┘ ┴└┘└────┘ ┴ ┴ ┴└─
txt ─────┘└───┘ ┴└┘└────┘ ┴ ┴ ┴└─
par ─────┘└───┘ ┴└──────┘ ┴ ┴ └──
pid ──────────┘ └───────┘ ┴ ┴ └──
st ─────────────────────────┘└──────────────────────────────────────────┘└─
1196 { rw [←lift_rel.swap R, ←lift_rel.swap], apply ST },
id └───────────┘ ┴ └───────────┘
src ───────┘└───┘└───────────┘┴ └─┘└───────────┘┴└┘└────┘ ┴└──
typ ───────┘└───┘└───────────┘┴┴└─┘└───────────┘┴└──────┘ └───
doc ───────┘└───┘ ┴ └─┘ ┴└┘└────┘ ┴└──
txt ───────┘└───┘ ┴ └─┘ ┴└┘└────┘ ┴└──
par ───────┘└───┘ ┴ └─┘ ┴└──────┘ └───
pid ────────────┘ ┴ └─┘ └───────┘ └───
st ──────┘└───────────────────┘└──────────────┘└──────────┘┴└─
1197 { rw [←lift_rel.swap R, ←lift_rel.swap (lift_rel R)],
id └───────────┘ ┴ └───────────┘ └──────┘ ┴
src ───────┘└───┘└───────────┘┴ └─┘└───────────┘┴ └──────┘┴ └┘└─
typ ───────┘└───┘└───────────┘┴┴└─┘└───────────┘┴ └──────┘┴┴└┘└─
doc ───────┘└───┘ ┴ └─┘ ┴ └──────┘┴ └┘└─
txt ───────┘└───┘ ┴ └─┘ ┴ ┴ └┘└─
par ───────┘└───┘ ┴ └─┘ ┴ ┴ └┘└─
pid ────────────┘ ┴ └─┘ ┴ ┴ └───
st ──────┘└───────────────────┘└───────────────────────────┘└──
1198 exact λ s1 s2 ⟨s, t, S, T, h1, h2, st, ST⟩,
id ┴ ┴ ┴ ┴ └┘ └┘ └┘ └┘
src ─────────────┘ └──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
typ ─────────────┘ └──────┘┴└┘┴└┘┴└┘┴└┘└┘└┘└┘└┘└┘└┘└┘└──
doc ─────────────┘ └──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
txt ─────────────┘ └──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
par ─────────────┘ └──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
pid ─────────────┘ └──────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └──
st ────────────────────────────────────────────────────
1199 ⟨t, s, T, S, h2, h1, st, ST⟩ },
src ─────────────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
typ ─────────────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
doc ─────────────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
txt ─────────────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
par ─────────────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
pid ─────────────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
st ──────────────────────────────────────────────────┘┴└─
1200 { exact mb } }
id └┘
src ─────────────┘ └────
typ ─────────────┘└┘└────
doc ─────────────┘ └────
txt ─────────────┘ └────
par ─────────────┘ └────
pid ─────────────┘ └────
st ────────────────┘└───
1201 end end
src ─────────┘
typ ─────────┘
doc ─────────┘
txt ─────────┘
par ─────────┘
pid ────────┘┴
st ────┘└───┘
1202 end⟩
st └─┘
1203
1204 theorem join_congr {S T : wseq (wseq α)} (h : lift_rel equiv S T) : join S ~ join T :=
id └──┘ └──┘ ┴ └──────┘ └───┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘ └──────┘ └───┘ └──┘ ┴ └──┘
typ └──┘ └──┘ ┴ └──────┘ └───┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘ └──────┘ └───┘ └──┘ ┴ └──┘
1205 lift_rel_join _ h
id └───────────┘ ┴
src └───────────┘
typ └───────────┘ ┴
1206
1207 theorem lift_rel_bind {δ} (R : α → β → Prop) (S : γ → δ → Prop)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
1208 {s1 : wseq α} {s2 : wseq β}
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
doc └──┘ └──┘
1209 {f1 : α → wseq γ} {f2 : β → wseq δ}
id ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
1210 (h1 : lift_rel R s1 s2) (h2 : ∀ {a b}, R a b → lift_rel S (f1 a) (f2 b))
id └──────┘ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ └┘ ┴ └┘ ┴
src └──────┘ └──────┘
typ └──────┘ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ └┘ ┴ └┘ ┴
doc └──────┘ └──────┘
1211 : lift_rel S (bind s1 f1) (bind s2 f2) :=
id └──────┘ ┴ └──┘ └┘ └┘ └──┘ └┘ └┘
src └──────┘ └──┘ └──┘
typ └──────┘ ┴ └──┘ └┘ └┘ └──┘ └┘ └┘
doc └──────┘ └──┘ └──┘
1212 lift_rel_join _ (lift_rel_map _ _ h1 @h2)
id └───────────┘ └──────────┘ └┘ └┘
src └───────────┘ └──────────┘
typ └───────────┘ └──────────┘ └┘ └┘
1213
1214 theorem bind_congr {s1 s2 : wseq α} {f1 f2 : α → wseq β}
id └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
1215 (h1 : s1 ~ s2) (h2 : ∀ a, f1 a ~ f2 a) : bind s1 f1 ~ bind s2 f2 :=
id └┘ ┴ └┘ ┴ └┘ ┴ ┴ └┘ ┴ └──┘ └┘ └┘ ┴ └──┘ └┘ └┘
src ┴ ┴ └──┘ ┴ └──┘
typ └┘ ┴ └┘ ┴ └┘ ┴ ┴ └┘ ┴ └──┘ └┘ └┘ ┴ └──┘ └┘ └┘
doc ┴ ┴ └──┘ ┴ └──┘
1216 lift_rel_bind _ _ h1 (λ a b h, by rw h; apply h2)
id └───────────┘ └┘ ┴ ┴ ┴ ┴
src └───────────┘ └─┘ └────┘
typ └───────────┘ └┘ ┴ ┴ ┴ └─┘┴ └────┘
doc └─┘ └────┘
txt └─┘ └────┘
par └─┘ └────┘
pid ┴ ┴
st └─────────────┘
1217
1218 @[simp] theorem join_ret (s : wseq α) : join (ret s) ~ s :=
id └──┘ ┴ └──┘ └─┘ ┴ ┴ ┴
src └──┘ └──┘ └─┘ ┴
typ └──┘ ┴ └──┘ └─┘ ┴ ┴ ┴
doc └──┘ └──┘ └──┘ └─┘ ┴
1219 by simp [ret]; apply think_equiv
id └─┘ └─────────┘
src └────┘└─┘┴ └────┘└─────────┘└
typ └────┘└─┘┴ └────┘└─────────┘└
doc └────┘└─┘┴ └────┘ └
txt └────┘ ┴ └────┘ └
par └────┘ ┴ └────┘ └
pid ┴┴ ┴ ┴ └
st └──────────────────────────────
1220
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1221 @[simp] theorem join_map_ret (s : wseq α) : join (map ret s) ~ s :=
id └──┘ ┴ └──┘ └─┘ └─┘ ┴ ┴ ┴
src └──┘ └──┘ └─┘ └─┘ ┴
typ └──┘ ┴ └──┘ └─┘ └─┘ ┴ ┴ ┴
doc └──┘ └──┘ └──┘ └─┘ └─┘ ┴
1222 begin
st └─────
1223 refine ⟨λ s1 s2, join (map ret s2) = s1, rfl, _⟩,
id └──┘ └─┘ └─┘ ┴ └─┘
src └─────┘ └──────┘└──┘┴ └─┘┴└─┘┴ └┘┴┴ └┘└─┘└──┘
typ └─────┘ └──────┘└──┘┴ └─┘┴└─┘┴ └┘┴┴ └┘└─┘└──┘
doc └─────┘ └──────┘└──┘┴ └─┘┴└─┘┴ └┘ ┴ └┘ └──┘
txt └─────┘ └──────┘ ┴ ┴ ┴ └┘ ┴ └┘ └──┘
par └─────┘ └──────┘ ┴ ┴ ┴ └┘ ┴ └┘ └──┘
pid ┴ └──────┘ ┴ ┴ ┴ └┘ ┴ └┘ └──┘
st ─────────────────────────────────────────────────┘└─
1224 intros s' s h, rw ←h,
id ┴
src └───────────┘ └──┘
typ └───────────┘ └──┘┴
doc └───────────┘ └──┘
txt └───────────┘ └──┘
par └───────────┘ └──┘
pid └─────┘ └┘
st ──────────────┘└─────┘└─
1225 apply lift_rel_rec
id └──────────┘
src └────┘└──────────┘└
typ └────┘└──────────┘└
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st ─────────────────────
1226 (λ c1 c2, ∃ s,
id ┴ ┴
src ───┘ └──────┘┴└┘┴└
typ ───┘ └──────┘┴└┘┴└
doc ───┘ └──────┘ └┘ └
txt ───┘ └──────┘ └┘ └
par ───┘ └──────┘ └┘ └
pid ───┘ └──────┘ └┘ └
st ───────────────────
1227 c1 = destruct (join (map ret s)) ∧ c2 = destruct s),
id └──┘ └─┘ └─┘ └──────┘
src ─────┘ ┴ ┴ ┴ └──┘┴ └─┘┴└─┘┴ └─┘ ┴ ┴ ┴└──────┘┴ ┴
typ ─────┘ ┴ ┴ ┴ └──┘┴ └─┘┴└─┘┴ └─┘ ┴ ┴ ┴└──────┘┴ ┴
doc ─────┘ ┴ ┴ ┴ └──┘┴ └─┘┴└─┘┴ └─┘ ┴ ┴ ┴└──────┘┴ ┴
txt ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
par ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
pid ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
st ────────────────────────────────────────────────────────┘└─
1228 { exact λ c1 c2 h, match c1, c2, h with
src └────┘ └────────┘ ┴ └┘ └┘ └─────
typ └────┘ └────────┘ ┴ └┘ └┘ └─────
doc └────┘ └────────┘ ┴ └┘ └┘ └─────
txt └────┘ └────────┘ ┴ └┘ └┘ └─────
par └────┘ └────────┘ ┴ └┘ └┘ └─────
pid ┴ └────────┘ ┴ └┘ └┘ └─────
st ───┘└─────────────────────────────────────
1229 | ._, ._, ⟨s, rfl, rfl⟩ := begin
src ─────┘ └┘ └┘ └┘ └┘ └───┘ └
typ ─────┘ └┘ └┘ └┘ └┘ └───┘ └
doc ─────┘ └┘ └┘ └┘ └┘ └───┘ └
txt ─────┘ └┘ └┘ └┘ └┘ └───┘ └
par ─────┘ └┘ └┘ └┘ └┘ └───┘ └
pid ─────┘ └┘ └┘ └┘ └┘ └───┘ └
st ──────────────────────────────┘└─────
1230 clear h _match,
src ─────┘└────────────┘└─
typ ─────┘└────────────┘└─
doc ─────┘└────────────┘└─
txt ─────┘└────────────┘└─
par ─────┘└────────────┘└─
pid ──────────────────────
st ───────────────────┘└─
1231 apply s.cases_on _ (λ a s, _) (λ s, _); simp [ret]; simp [ret],
id └────────┘ └─┘ └─┘
src ─────┘└────┘└────────┘└─┘ └───────┘ └────┘└┘└────┘└─┘┴└┘└────┘└─┘┴└─
typ ───────────┘└────────┘└─┘ └───────┘ └──────┘└────┘└─┘┴└┘└────┘└─┘┴└─
doc ─────┘└────┘ └─┘ └───────┘ └────┘└┘└────┘└─┘┴└┘└────┘└─┘┴└─
txt ─────┘└────┘ └─┘ └───────┘ └────┘└┘└────┘ ┴└┘└────┘ ┴└─
par ───────────┘ └─┘ └───────┘ └──────┘└────┘ ┴└┘└────┘ ┴└─
pid ───────────┘ └─┘ └───────┘ └────────────┘ └───────┘ └──
st ───────────────────────────────────────────────────────────────────┘└─
1232 { refine ⟨_, ret_mem _, _⟩, simp },
id └─────┘
src ───────┘└─────┘ └─┘└─────┘└────┘└┘└───┘└──
typ ──────────────┘ └─┘└─────┘└──────┘└───┘└──
doc ───────┘└─────┘ └─┘ └────┘└┘└───┘└──
txt ───────┘└─────┘ └─┘ └────┘└┘└───┘└──
par ──────────────┘ └─┘ └──────┘└───┘└──
pid ──────────────┘ └─┘ └───────────────
st ──────┘└───────────────────────┘└─────┘┴└─
1233 { exact ⟨s, rfl, rfl⟩ }
id ┴ └─┘
src ─────────────┘ └┘ └┘└─┘└───
typ ─────────────┘ ┴└┘ └┘└─┘└───
doc ─────────────┘ └┘ └┘ └───
txt ─────────────┘ └┘ └┘ └───
par ─────────────┘ └┘ └┘ └───
pid ─────────────┘ └┘ └┘ └───
st ───────────────────────────┘└─
1234 end end },
src ───────────┘
typ ───────────┘
doc ───────────┘
txt ───────────┘
par ───────────┘
pid ──────────┘┴
st ──────┘└───┘└┘└
1235 { exact ⟨s, rfl, rfl⟩ }
id ┴ └─┘
src └────┘ └┘ └┘└─┘└┘
typ └────┘ ┴└┘ └┘└─┘└┘
doc └────┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘
pid ┴ └┘ └┘ ┴┴
st ───────────────────────┘└─
1236 end
st ──┘
1237
1238 @[simp] theorem join_append (S T : wseq (wseq α)) :
id └──┘ └──┘ ┴
src └──┘ └──┘
typ └──┘ └──┘ ┴
doc └──┘ └──┘ └──┘
1239 join (append S T) ~ append (join S) (join T) :=
id └──┘ └────┘ ┴ ┴ ┴ └────┘ └──┘ ┴ └──┘ ┴
src └──┘ └────┘ ┴ └────┘ └──┘ └──┘
typ └──┘ └────┘ ┴ ┴ ┴ └────┘ └──┘ ┴ └──┘ ┴
doc └──┘ └────┘ ┴ └────┘ └──┘ └──┘
1240 begin
st └─────
1241 refine ⟨λ s1 s2, ∃ s S T,
id ┴ ┴
src └─────┘ └──────┘┴└────┘┴└
typ └─────┘ └──────┘┴└────┘┴└
doc └─────┘ └──────┘ └────┘ └
txt └─────┘ └──────┘ └────┘ └
par └─────┘ └──────┘ └────┘ └
pid ┴ └──────┘ └────┘ └
st ────────────────────────────
1242 s1 = append s (join (append S T)) ∧
id ┴ ┴
src ───┘ ┴┴┴ ┴ ┴ ┴ ┴ ┴ └─┘┴└
typ ───┘ ┴┴┴ ┴ ┴ ┴ ┴ ┴ └─┘┴└
doc ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
st ────────────────────────────────────────
1243 s2 = append s (append (join S) (join T)), ⟨nil, S, T, by simp, by simp⟩, _⟩,
id └────┘ └──┘ └─┘ ┴ ┴
src ───┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └──┘┴ └──┘ └─┘└┘ └┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
typ ───┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └──┘┴ └──┘ └─┘└┘┴└┘┴└┘ ┴└──┘└┘ ┴└──┘└───┘
doc ───┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └──┘┴ └──┘ └─┘└┘ └┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ └┘ └┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ └┘ └┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ └┘ └┘ └┘ └─────┘ └────────┘
st ───────────────────────────────────────────────────────────┘└───┘└──┘└───┘└───┘└─
1244 intros s1 s2 h,
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid └──────┘
st ───────────────┘└─
1245 apply lift_rel_rec (λ c1 c2, ∃ (s : wseq α) S T,
id └──────────┘ ┴ └──┘ ┴ ┴
src └────┘└──────────┘┴ └──────┘┴└────┘└──┘┴ └───┘┴└
typ └────┘└──────────┘┴ └──────┘┴└────┘└──┘┴┴└───┘┴└
doc └────┘ ┴ └──────┘ └────┘└──┘┴ └───┘ └
txt └────┘ ┴ └──────┘ └────┘ ┴ └───┘ └
par └────┘ ┴ └──────┘ └────┘ ┴ └───┘ └
pid ┴ ┴ └──────┘ └────┘ ┴ └───┘ └
st ───────────────────────────────────────────────────
1246 c1 = destruct (append s (join (append S T))) ∧
src ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
typ ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
doc ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
st ───────────────────────────────────────────────────
1247 c2 = destruct (append s (append (join S) (join T)))) _ _ _
id └────┘ └──┘
src ───┘ ┴ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └──┘┴ └──────────
typ ───┘ ┴ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └──┘┴ └──────────
doc ───┘ ┴ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ └──┘┴ └──────────
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──────────
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──────────
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └──────────
st ───────────────────────────────────────────────────────────────
1248 (let ⟨s, S, T, h1, h2⟩ := h in
id ┴ ┴ ┴ └┘ └┘ ┴
src ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └───
typ ───┘ ┴ ┴└┘┴└┘┴└┘└┘└┘└┘└───┘┴└───
doc ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └───
txt ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └───
par ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └───
pid ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └───
st ───────────────────────────────────
1249 ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩),
id └───────┘ └──────┘
src ────────┘ └┘ └┘ └┘ ┴ ┴ └┘└───────┘┴└──────┘┴ └┘
typ ────────┘ └┘ └┘ └┘ ┴ ┴ └┘└───────┘┴└──────┘┴ └┘
doc ────────┘ └┘ └┘ └┘ ┴ ┴ └┘ ┴└──────┘┴ └┘
txt ────────┘ └┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ └┘
par ────────┘ └┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ └┘
pid ────────┘ └┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ └┘
st ────────────────────────────────────────────────────────────────┘└─
1250 intros c1 c2 h,
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid └──────┘
st ───────────────┘└─
1251 exact match c1, c2, h with ._, ._, ⟨s, S, T, rfl, rfl⟩ := begin
id └┘ └┘ ┴ └─┘
src └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘└─┘└───┘ └
typ └────┘ ┴└┘└┘└┘└┘┴└────┘ └┘ └┘ └┘ └┘ └┘ └┘└─┘└───┘ └
doc └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
txt └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
par └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
pid ┴ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
st ───────────────────────────────────────────────────────────┘└─────
1252 clear _match h h,
src ───┘└──────────────┘└─
typ ───┘└──────────────┘└─
doc ───┘└──────────────┘└─
txt ───┘└──────────────┘└─
par ───┘└──────────────┘└─
pid ──────────────────────
st ───────────────────┘└─
1253 apply wseq.cases_on s _ (λ a s, _) (λ s, _); simp; simp,
id └───────────┘ ┴
src ───┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ─────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ───┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ───┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ─────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ─────────┘ ┴ └─┘ └───────┘ └───────────────────
st ──────────────────────────────────────────────────────────┘└─
1254 { apply wseq.cases_on S _ (λ s S, _) (λ S, _); simp; simp,
id └───────────┘ ┴
src ─────┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ───────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ─────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ─────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ───────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ───────────┘ ┴ └─┘ └───────┘ └───────────────────
st ────┘└──────────────────────────────────────────────────────┘└─
1255 { apply wseq.cases_on T _ (λ s T, _) (λ T, _); simp; simp,
id └───────────┘ ┴
src ───────┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ─────────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ───────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ───────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ─────────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ─────────────┘ ┴ └─┘ └───────┘ └───────────────────
st ──────┘└──────────────────────────────────────────────────────┘└─
1256 { refine ⟨s, nil, T, _, _⟩; simp },
id ┴ └─┘ ┴
src ─────────┘└─────┘ └┘└─┘└┘ └─────┘└┘└───┘└──
typ ────────────────┘ ┴└┘└─┘└┘┴└───────┘└───┘└──
doc ─────────┘└─────┘ └┘└─┘└┘ └─────┘└┘└───┘└──
txt ─────────┘└─────┘ └┘ └┘ └─────┘└┘└───┘└──
par ────────────────┘ └┘ └┘ └───────┘└───┘└──
pid ────────────────┘ └┘ └┘ └────────────────
st ────────┘└──────────────────────────────┘┴└─
1257 { refine ⟨nil, nil, T, _, _⟩; simp } },
id └─┘ ┴
src ─────────┘└─────┘ └┘└─┘└┘ └─────┘└┘└───┘└────
typ ────────────────┘ └┘└─┘└┘┴└───────┘└───┘└────
doc ─────────┘└─────┘ └┘└─┘└┘ └─────┘└┘└───┘└────
txt ─────────┘└─────┘ └┘ └┘ └─────┘└┘└───┘└────
par ────────────────┘ └┘ └┘ └───────┘└───┘└────
pid ────────────────┘ └┘ └┘ └──────────────────
st ──────────────────────────────────────────┘└─┘└─
1258 { exact ⟨s, S, T, rfl, rfl⟩ },
id ┴ ┴ ┴ └─┘
src ─────────────┘ └┘ └┘ └┘ └┘└─┘└────
typ ─────────────┘ ┴└┘┴└┘┴└┘ └┘└─┘└────
doc ─────────────┘ └┘ └┘ └┘ └┘ └────
txt ─────────────┘ └┘ └┘ └┘ └┘ └────
par ─────────────┘ └┘ └┘ └┘ └┘ └────
pid ─────────────┘ └┘ └┘ └┘ └┘ └────
st ──────┘└─────────────────────────┘┴└─
1259 { refine ⟨nil, S, T, _, _⟩; simp } },
id └─┘ ┴ ┴
src ───────┘└─────┘ └─┘└┘ └┘ └─────┘└┘└───┘└────
typ ──────────────┘ └─┘└┘┴└┘┴└───────┘└───┘└────
doc ───────┘└─────┘ └─┘└┘ └┘ └─────┘└┘└───┘└────
txt ───────┘└─────┘ └┘ └┘ └─────┘└┘└───┘└────
par ──────────────┘ └┘ └┘ └───────┘└───┘└────
pid ──────────────┘ └┘ └┘ └──────────────────
st ──────────────────────────────────────┘└─┘└─
1260 { exact ⟨s, S, T, rfl, rfl⟩ },
id ┴ ┴ ┴ └─┘
src ───────────┘ └┘ └┘ └┘ └┘└─┘└────
typ ───────────┘ ┴└┘┴└┘┴└┘ └┘└─┘└────
doc ───────────┘ └┘ └┘ └┘ └┘ └────
txt ───────────┘ └┘ └┘ └┘ └┘ └────
par ───────────┘ └┘ └┘ └┘ └┘ └────
pid ───────────┘ └┘ └┘ └┘ └┘ └────
st ────┘└─────────────────────────┘┴└─
1261 { exact ⟨s, S, T, rfl, rfl⟩ }
id ┴ ┴ ┴ └─┘
src ───────────┘ └┘ └┘ └┘ └┘└─┘└───
typ ───────────┘ ┴└┘┴└┘┴└┘ └┘└─┘└───
doc ───────────┘ └┘ └┘ └┘ └┘ └───
txt ───────────┘ └┘ └┘ └┘ └┘ └───
par ───────────┘ └┘ └┘ └┘ └┘ └───
pid ───────────┘ └┘ └┘ └┘ └┘ └───
st ───────────────────────────────┘└─
1262 end end
src ─────────┘
typ ─────────┘
doc ─────────┘
txt ─────────┘
par ─────────┘
pid ────────┘┴
st ────┘└───┘
1263 end
st └─┘
1264
1265 @[simp] theorem bind_ret (f : α → β) (s) : bind s (ret ∘ f) ~ map f s :=
id ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ └─┘ ┴ ┴ └─┘
typ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └──┘ └──┘ └─┘ ┴ └─┘
1266 begin
st └─────
1267 dsimp [bind], change (λx, ret (f x)) with (ret ∘ f),
id └──┘ └─┘ ┴ └─┘ ┴ ┴
src └─────┘└──┘┴ └─────┘ └─┘└─┘┴ ┴ └──────┘ └─┘┴┴┴ ┴
typ └─────┘└──┘┴ └─────┘ └─┘└─┘┴ ┴┴ └──────┘ └─┘┴┴┴┴┴
doc └─────┘└──┘┴ └─────┘ └─┘└─┘┴ ┴ └──────┘ └─┘┴ ┴ ┴
txt └─────┘ ┴ └─────┘ └─┘ ┴ ┴ └──────┘ ┴ ┴ ┴
par └─────┘ ┴ └─────┘ └─┘ ┴ ┴ └──────┘ ┴ ┴ ┴
pid ┴┴ ┴ ┴ └─┘ ┴ ┴ └┘└────┘ ┴ ┴ ┴
st ─────────────┘└────────────────────────────────────────
1268 rw [map_comp], apply join_map_ret
id └──────┘ └──────────┘
src └──┘└──────┘┴ └────┘└──────────┘┴
typ └──┘└──────┘┴ └────┘└──────────┘┴
doc └──┘ ┴ └────┘ ┴
txt └──┘ ┴ └────┘ ┴
par └──┘ ┴ └────┘ ┴
pid └┘ ┴ ┴ ┴
st ─────────────┘└────────────────────┘
1269 end
st └─┘
1270
1271 @[simp] theorem ret_bind (a : α) (f : α → wseq β) :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
doc └──┘ └──┘
1272 bind (ret a) f ~ f a := by simp [bind]
id └──┘ └─┘ ┴ ┴ ┴ ┴ ┴ └──┘
src └──┘ └─┘ ┴ └────┘└──┘└─
typ └──┘ └─┘ ┴ ┴ ┴ ┴ ┴ └────┘└──┘└─
doc └──┘ └─┘ ┴ └────┘└──┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └────────────
1273
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1274 @[simp] theorem map_join (f : α → β) (S) :
id ┴ ┴
typ ┴ ┴
doc └──┘
1275 map f (join S) = join (map (map f) S) :=
id └─┘ ┴ └──┘ ┴ ┴ └──┘ └─┘ └─┘ ┴ ┴
src └─┘ └──┘ ┴ └──┘ └─┘ └─┘
typ └─┘ ┴ └──┘ ┴ ┴ └──┘ └─┘ └─┘ ┴ ┴
doc └─┘ └──┘ └──┘ └─┘ └─┘
1276 begin
st └─────
1277 apply seq.eq_of_bisim (λs1 s2,
id └─────────────┘
src └────┘└─────────────┘┴ └──────
typ └────┘└─────────────┘┴ └──────
doc └────┘ ┴ └──────
txt └────┘ ┴ └──────
par └────┘ ┴ └──────
pid ┴ ┴ └──────
st ─────────────────────────────────
1278 ∃ s S, s1 = append s (map f (join S)) ∧
id ┴ ┴ ┴ ┴
src ───┘┴└──┘┴┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴ └─┘┴└
typ ───┘┴└──┘┴┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴ └─┘┴└
doc ───┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
txt ───┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
par ───┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
pid ───┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └
st ────────────────────────────────────────────
1279 s2 = append s (join (map (map f) S))),
id └────┘ └──┘ └─┘ ┴
src ─────┘ ┴ ┴└────┘┴ ┴ └──┘┴ ┴ └─┘┴ └┘ └─┘
typ ─────┘ ┴ ┴└────┘┴ ┴ └──┘┴ ┴ └─┘┴┴└┘ └─┘
doc ─────┘ ┴ ┴└────┘┴ ┴ └──┘┴ ┴ └─┘┴ └┘ └─┘
txt ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─┘
par ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─┘
pid ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─┘
st ──────────────────────────────────────────┘└─
1280 { intros s1 s2 h,
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid └──────┘
st ───┘└────────────┘└─
1281 exact match s1, s2, h with ._, ._, ⟨s, S, rfl, rfl⟩ := begin
id └┘ └┘ ┴ └─┘
src └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘└─┘└───┘ └
typ └────┘ ┴└┘└┘└┘└┘┴└────┘ └┘ └┘ └┘ └┘ └┘└─┘└───┘ └
doc └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
txt └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
par └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
pid ┴ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
st ──────────────────────────────────────────────────────────┘└─────
1282 apply wseq.cases_on s _ (λ a s, _) (λ s, _); simp; simp,
id └───────────┘ ┴
src ─────┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ───────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ─────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ─────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ───────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ───────────┘ ┴ └─┘ └───────┘ └───────────────────
st ────────────────────────────────────────────────────────────┘└─
1283 { apply wseq.cases_on S _ (λ s S, _) (λ S, _); simp; simp,
id └───────────┘ ┴
src ───────┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ─────────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ───────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ───────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ─────────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ─────────────┘ ┴ └─┘ └───────┘ └───────────────────
st ──────┘└──────────────────────────────────────────────────────┘└─
1284 { exact ⟨map f s, S, rfl, rfl⟩ },
id └─┘ ┴ ┴ ┴ └─┘
src ───────────────┘ └─┘┴ ┴ └┘ └┘ └┘└─┘└────
typ ───────────────┘ └─┘┴┴┴┴└┘┴└┘ └┘└─┘└────
doc ───────────────┘ └─┘┴ ┴ └┘ └┘ └┘ └────
txt ───────────────┘ ┴ ┴ └┘ └┘ └┘ └────
par ───────────────┘ ┴ ┴ └┘ └┘ └┘ └────
pid ───────────────┘ ┴ ┴ └┘ └┘ └┘ └────
st ────────┘└────────────────────────────┘┴└─
1285 { refine ⟨nil, S, _, _⟩; simp } },
id └─┘ ┴
src ─────────┘└─────┘ └─┘└┘ └─────┘└┘└───┘└────
typ ────────────────┘ └─┘└┘┴└───────┘└───┘└────
doc ─────────┘└─────┘ └─┘└┘ └─────┘└┘└───┘└────
txt ─────────┘└─────┘ └┘ └─────┘└┘└───┘└────
par ────────────────┘ └┘ └───────┘└───┘└────
pid ────────────────┘ └┘ └──────────────────
st ─────────────────────────────────────┘└─┘└─
1286 { exact ⟨_, _, rfl, rfl⟩ },
id └─┘
src ─────────────┘ └────┘ └┘└─┘└────
typ ─────────────┘ └────┘ └┘└─┘└────
doc ─────────────┘ └────┘ └┘ └────
txt ─────────────┘ └────┘ └┘ └────
par ─────────────┘ └────┘ └┘ └────
pid ─────────────┘ └────┘ └┘ └────
st ──────┘└──────────────────────┘┴└─
1287 { exact ⟨_, _, rfl, rfl⟩ }
id └─┘
src ─────────────┘ └────┘ └┘└─┘└───
typ ─────────────┘ └────┘ └┘└─┘└───
doc ─────────────┘ └────┘ └┘ └───
txt ─────────────┘ └────┘ └┘ └───
par ─────────────┘ └────┘ └┘ └───
pid ─────────────┘ └────┘ └┘ └───
st ──────────────────────────────┘└─
1288 end end },
src ───────────┘
typ ───────────┘
doc ───────────┘
txt ───────────┘
par ───────────┘
pid ──────────┘┴
st ──────┘└───┘└┘└
1289 { refine ⟨nil, S, _, _⟩; simp }
id └─┘ ┴
src └─────┘ └─┘└┘ └─────┘ └───┘
typ └─────┘ └─┘└┘┴└─────┘ └───┘
doc └─────┘ └─┘└┘ └─────┘ └───┘
txt └─────┘ └┘ └─────┘ └───┘
par └─────┘ └┘ └─────┘ └───┘
pid ┴ └┘ └─────┘ ┴
st ───────────────────────────────┘└─
1290 end
st ──┘
1291
1292 @[simp] theorem join_join (SS : wseq (wseq (wseq α))) :
id └──┘ └──┘ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ └──┘ └──┘ ┴
doc └──┘ └──┘ └──┘ └──┘
1293 join (join SS) ~ join (map join SS) :=
id └──┘ └──┘ └┘ ┴ └──┘ └─┘ └──┘ └┘
src └──┘ └──┘ ┴ └──┘ └─┘ └──┘
typ └──┘ └──┘ └┘ ┴ └──┘ └─┘ └──┘ └┘
doc └──┘ └──┘ ┴ └──┘ └─┘ └──┘
1294 begin
st └─────
1295 refine ⟨λ s1 s2, ∃ s S SS,
id ┴ ┴
src └─────┘ └──────┘┴└─────┘┴└
typ └─────┘ └──────┘┴└─────┘┴└
doc └─────┘ └──────┘ └─────┘ └
txt └─────┘ └──────┘ └─────┘ └
par └─────┘ └──────┘ └─────┘ └
pid ┴ └──────┘ └─────┘ └
st ─────────────────────────────
1296 s1 = append s (join (append S (join SS))) ∧
id ┴ ┴
src ───┘ ┴┴┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘┴└
typ ───┘ ┴┴┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘┴└
doc ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └
st ────────────────────────────────────────────────
1297 s2 = append s (append (join S) (join (map join SS))),
id └────┘ └─┘ └──┘
src ───┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ ┴ └─┘┴└──┘┴ └────
typ ───┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ ┴ └─┘┴└──┘┴ └────
doc ───┘ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ ┴ └─┘┴└──┘┴ └────
txt ───┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └────
par ───┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └────
pid ───┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └────
st ──────────────────────────────────────────────────────────
1298 ⟨nil, nil, SS, by simp, by simp⟩, _⟩,
id └─┘ └┘
src ───┘ └┘└─┘└┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
typ ───┘ └┘└─┘└┘└┘└┘ ┴└──┘└┘ ┴└──┘└───┘
doc ───┘ └┘└─┘└┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
txt ───┘ └┘ └┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
par ───┘ └┘ └┘ └┘ ┴└──┘└┘ ┴└──┘└───┘
pid ───┘ └┘ └┘ └┘ └─────┘ └────────┘
st ────────────────────┘└───┘└──┘└───┘└───┘└─
1299 intros s1 s2 h,
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid └──────┘
st ───────────────┘└─
1300 apply lift_rel_rec (λ c1 c2, ∃ s S SS,
id └──────────┘ ┴ ┴
src └────┘└──────────┘┴ └──────┘┴└─────┘┴└
typ └────┘└──────────┘┴ └──────┘┴└─────┘┴└
doc └────┘ ┴ └──────┘ └─────┘ └
txt └────┘ ┴ └──────┘ └─────┘ └
par └────┘ ┴ └──────┘ └─────┘ └
pid ┴ ┴ └──────┘ └─────┘ └
st ─────────────────────────────────────────
1301 c1 = destruct (append s (join (append S (join SS)))) ∧
src ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ └
typ ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ └
doc ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ └
txt ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ └
par ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ └
pid ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ └
st ─────────────────────────────────────────────────────────────
1302 c2 = destruct (append s (append (join S) (join (map join SS)))))
id └────┘ └─┘ └──┘
src ─────┘ ┴ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ ┴ └─┘┴└──┘┴ └─────
typ ─────┘ ┴ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ ┴ └─┘┴└──┘┴ └─────
doc ─────┘ ┴ ┴ ┴ ┴ ┴ └────┘┴ ┴ └┘ ┴ └─┘┴└──┘┴ └─────
txt ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─────
par ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─────
pid ─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─────
st ───────────────────────────────────────────────────────────────────────
1303 _ (destruct s1) (destruct s2)
id └┘ └──────┘ └┘
src ─────┘ ┴ └┘ └──────┘┴ └─
typ ─────┘ ┴└┘└┘ └──────┘┴└┘└─
doc ─────┘ ┴ └┘ └──────┘┴ └─
txt ─────┘ ┴ └┘ ┴ └─
par ─────┘ ┴ └┘ ┴ └─
pid ─────┘ ┴ └┘ ┴ └─
st ──────────────────────────────────
1304 (let ⟨s, S, SS, h1, h2⟩ := h in ⟨s, S, SS, by simp [h1], by simp [h2]⟩),
id ┴ ┴ └┘ ┴ └┘ └┘
src ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └──┘ └┘ └┘ └┘ ┴└────┘ ┴└┘ ┴└────┘ ┴└┘
typ ───┘ ┴ ┴└┘┴└┘└┘└┘ └┘ └───┘┴└──┘ └┘ └┘ └┘ ┴└────┘└┘┴└┘ ┴└────┘└┘┴└┘
doc ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └──┘ └┘ └┘ └┘ ┴└────┘ ┴└┘ ┴└────┘ ┴└┘
txt ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └──┘ └┘ └┘ └┘ ┴└────┘ ┴└┘ ┴└────┘ ┴└┘
par ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └──┘ └┘ └┘ └┘ ┴└────┘ ┴└┘ ┴└────┘ ┴└┘
pid ───┘ ┴ └┘ └┘ └┘ └┘ └───┘ └──┘ └┘ └┘ └┘ └─────┘ └─┘ └─────┘ └─┘
st ────────────────────────────────────────────────┘└────────┘└──┘└────────┘└┘└─
1305 intros c1 c2 h,
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid └──────┘
st ───────────────┘└─
1306 exact match c1, c2, h with ._, ._, ⟨s, S, SS, rfl, rfl⟩ := begin
id └┘ └┘ ┴ └─┘
src └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘└─┘└───┘ └
typ └────┘ ┴└┘└┘└┘└┘┴└────┘ └┘ └┘ └┘ └┘ └┘ └┘└─┘└───┘ └
doc └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
txt └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
par └────┘ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
pid ┴ ┴ └┘ └┘ └────┘ └┘ └┘ └┘ └┘ └┘ └┘ └───┘ └
st ────────────────────────────────────────────────────────────┘└─────
1307 clear _match h h,
src ───┘└──────────────┘└─
typ ───┘└──────────────┘└─
doc ───┘└──────────────┘└─
txt ───┘└──────────────┘└─
par ───┘└──────────────┘└─
pid ──────────────────────
st ───────────────────┘└─
1308 apply wseq.cases_on s _ (λ a s, _) (λ s, _); simp; simp,
id └───────────┘ ┴
src ───┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ─────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ───┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ───┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ─────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ─────────┘ ┴ └─┘ └───────┘ └───────────────────
st ──────────────────────────────────────────────────────────┘└─
1309 { apply wseq.cases_on S _ (λ s S, _) (λ S, _); simp; simp,
id └───────────┘ ┴
src ─────┘└────┘└───────────┘┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
typ ───────────┘└───────────┘┴┴└─┘ └───────┘ └──────┘└──┘└┘└──┘└─
doc ─────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
txt ─────┘└────┘ ┴ └─┘ └───────┘ └────┘└┘└──┘└┘└──┘└─
par ───────────┘ ┴ └─┘ └───────┘ └──────┘└──┘└┘└──┘└─
pid ───────────┘ ┴ └─┘ └───────┘ └───────────────────
st ────┘└──────────────────────────────────────────────────────┘└─
1310 { apply wseq.cases_on SS _ (λ S SS, _) (λ SS, _); simp; simp,
id └───────────┘ └┘
src ───────┘└────┘└───────────┘┴ └─┘ └────────┘ └─────┘└┘└──┘└┘└──┘└─
typ ─────────────┘└───────────┘┴└┘└─┘ └────────┘ └───────┘└──┘└┘└──┘└─
doc ───────┘└────┘ ┴ └─┘ └────────┘ └─────┘└┘└──┘└┘└──┘└─
txt ───────┘└────┘ ┴ └─┘ └────────┘ └─────┘└┘└──┘└┘└──┘└─
par ─────────────┘ ┴ └─┘ └────────┘ └───────┘└──┘└┘└──┘└─
pid ─────────────┘ ┴ └─┘ └────────┘ └────────────────────
st ──────┘└─────────────────────────────────────────────────────────┘└─
1311 { refine ⟨nil, S, SS, _, _⟩; simp },
id └─┘ ┴ └┘
src ─────────┘└─────┘ └─┘└┘ └┘ └─────┘└┘└───┘└──
typ ────────────────┘ └─┘└┘┴└┘└┘└───────┘└───┘└──
doc ─────────┘└─────┘ └─┘└┘ └┘ └─────┘└┘└───┘└──
txt ─────────┘└─────┘ └┘ └┘ └─────┘└┘└───┘└──
par ────────────────┘ └┘ └┘ └───────┘└───┘└──
pid ────────────────┘ └┘ └┘ └────────────────
st ────────┘└───────────────────────────────┘┴└─
1312 { refine ⟨nil, nil, SS, _, _⟩; simp } },
id └─┘ └┘
src ─────────┘└─────┘ └┘└─┘└┘ └─────┘└┘└───┘└────
typ ────────────────┘ └┘└─┘└┘└┘└───────┘└───┘└────
doc ─────────┘└─────┘ └┘└─┘└┘ └─────┘└┘└───┘└────
txt ─────────┘└─────┘ └┘ └┘ └─────┘└┘└───┘└────
par ────────────────┘ └┘ └┘ └───────┘└───┘└────
pid ────────────────┘ └┘ └┘ └──────────────────
st ───────────────────────────────────────────┘└─┘└─
1313 { exact ⟨s, S, SS, rfl, rfl⟩ },
id ┴ ┴ └┘ └─┘
src ─────────────┘ └┘ └┘ └┘ └┘└─┘└────
typ ─────────────┘ ┴└┘┴└┘└┘└┘ └┘└─┘└────
doc ─────────────┘ └┘ └┘ └┘ └┘ └────
txt ─────────────┘ └┘ └┘ └┘ └┘ └────
par ─────────────┘ └┘ └┘ └┘ └┘ └────
pid ─────────────┘ └┘ └┘ └┘ └┘ └────
st ──────┘└──────────────────────────┘┴└─
1314 { refine ⟨nil, S, SS, _, _⟩; simp } },
id └─┘ ┴ └┘
src ───────┘└─────┘ └─┘└┘ └┘ └─────┘└┘└───┘└────
typ ──────────────┘ └─┘└┘┴└┘└┘└───────┘└───┘└────
doc ───────┘└─────┘ └─┘└┘ └┘ └─────┘└┘└───┘└────
txt ───────┘└─────┘ └┘ └┘ └─────┘└┘└───┘└────
par ──────────────┘ └┘ └┘ └───────┘└───┘└────
pid ──────────────┘ └┘ └┘ └──────────────────
st ───────────────────────────────────────┘└─┘└─
1315 { exact ⟨s, S, SS, rfl, rfl⟩ },
id ┴ ┴ └┘ └─┘
src ───────────┘ └┘ └┘ └┘ └┘└─┘└────
typ ───────────┘ ┴└┘┴└┘└┘└┘ └┘└─┘└────
doc ───────────┘ └┘ └┘ └┘ └┘ └────
txt ───────────┘ └┘ └┘ └┘ └┘ └────
par ───────────┘ └┘ └┘ └┘ └┘ └────
pid ───────────┘ └┘ └┘ └┘ └┘ └────
st ────┘└──────────────────────────┘┴└─
1316 { exact ⟨s, S, SS, rfl, rfl⟩ }
id ┴ ┴ └┘ └─┘
src ───────────┘ └┘ └┘ └┘ └┘└─┘└───
typ ───────────┘ ┴└┘┴└┘└┘└┘ └┘└─┘└───
doc ───────────┘ └┘ └┘ └┘ └┘ └───
txt ───────────┘ └┘ └┘ └┘ └┘ └───
par ───────────┘ └┘ └┘ └┘ └┘ └───
pid ───────────┘ └┘ └┘ └┘ └┘ └───
st ────────────────────────────────┘└─
1317 end end
src ─────────┘
typ ─────────┘
doc ─────────┘
txt ─────────┘
par ─────────┘
pid ────────┘┴
st ────┘└───┘
1318 end
st └─┘
1319
1320 @[simp] theorem bind_assoc (s : wseq α) (f : α → wseq β) (g : β → wseq γ) :
id └──┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴
doc └──┘ └──┘ └──┘ └──┘
1321 bind (bind s f) g ~ bind s (λ (x : α), bind (f x) g) :=
id └──┘ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴
src └──┘ └──┘ ┴ └──┘ └──┘
typ └──┘ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴
doc └──┘ └──┘ ┴ └──┘ └──┘
1322 begin
st └─────
1323 simp [bind], rw [← map_comp f (map g), map_comp (map g ∘ f) join],
id └──┘ └──────┘ ┴ └─┘ ┴ └──────┘ └─┘ ┴ ┴ ┴ └──┘
src └────┘└──┘┴ └────┘└──────┘┴ ┴ └─┘┴ └─┘└──────┘┴ └─┘┴ ┴┴┴ └┘└──┘┴
typ └────┘└──┘┴ └────┘└──────┘┴┴┴ └─┘┴┴└─┘└──────┘┴ └─┘┴┴┴┴┴┴└┘└──┘┴
doc └────┘└──┘┴ └────┘ ┴ ┴ └─┘┴ └─┘ ┴ └─┘┴ ┴ ┴ └┘└──┘┴
txt └────┘ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └┘ ┴
par └────┘ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └┘ ┴
pid ┴┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └┘ ┴
st ────────────┘└────────────────────────┘└─────────────────────────┘└──
1324 apply join_join
id └───────┘
src └────┘└───────┘┴
typ └────┘└───────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ─────────────────┘
1325 end
st └─┘
1326
1327 instance : monad wseq :=
id └───┘ └──┘
src └───┘ └──┘
typ └───┘ └──┘
doc └──┘
1328 { map := @map,
id └─┘
src └─┘
typ └─┘
doc └─┘
1329 pure := @ret,
id └─┘
src └─┘
typ └─┘
doc └─┘
1330 bind := @bind }
id └──┘
src └──┘
typ └──┘
doc └──┘
1331
1332 /-
1333 Unfortunately, wseq is not a lawful monad, because it does not satisfy
1334 the monad laws exactly, only up to sequence equivalence.
1335 Furthermore, even quotienting by the equivalence is not sufficient,
1336 because the join operation involves lists of quotient elements,
1337 with a lifted equivalence relation, and pure quotients cannot handle
1338 this type of construction.
1339
1340 instance : is_lawful_monad wseq :=
1341 { id_map := @map_id,
1342 bind_pure_comp_eq_map := @bind_ret,
1343 pure_bind := @ret_bind,
1344 bind_assoc := @bind_assoc }
1345 -/
1346
1347 end wseq